Hi,
I’m currently checking if my Scala 2 project (which uses Tapir) can be migrated to Scala 3.
I’ve reached one compiler-error, which I don’t fully understand, and I hope maybe someone here could help me with understanding it.
My API uses a 3rd-party library called Diffson JsonPatch, which provides a sealed type for defining patch-operations:
sealed abstract class Operation[Json: Jsony]
case class Add[Json: Jsony](path: Pointer, value: Json) extends Operation[Json]
case class Move ...
case class Remove ...
My Scala 2 code includes a manual definition for Schema[Operation[JsValue]]
which is manually built (with some helpers), and relies on the Schema.derived
method for all the sub-types:
implicit lazy val jsonPatchOperationSchema: Schema[Operation[JsValue]] =
Schema
.any[Operation[JsValue]]
.name(SName("JsonPatchOperation"))
.discriminatorKey("op")
.addSubType("add", Schema.derived[Add[JsValue]].name(SName("JsonPatchAdd")))
.addSubType("move", ...)
...
where discriminatorKey
and addSubType
are my custom helper methods, but that does not matter because it’s not the cause of the issue.
The problem now is that Scala 3 compiler does not like the Schema.derived[Add[JsValue]]
call:
No given instance of type scala.deriving.Mirror.Of[diffson.jsonpatch.Add[play.api.libs.json.JsValue]] was found for parameter m of method derived in trait SchemaMagnoliaDerivation. Failed to synthesize an instance of type scala.deriving.Mirror.Of[diffson.jsonpatch.Add[play.api.libs.json.JsValue]]:
* class Add is not a generic product because it takes more than one parameter list
* class Add is not a generic sum because it is not a sealed class [41:54]
So, I understand and agree with the error statement - Add
is not a sealed class itself, and it has 2 parameters, which is more than 1.
But why there are those constraints for Mirror.Of
hence for Schema.derived
?
And how can I overcome it and derive a schema for a case class with a generic type and more than one param?
Thanks in advance.