вы можете использовать circe-generic и добавить маркировку типов для ваших jsons:
В вашем build.sbt:
libraryDependencies ++= Seq(
"io.circe" %% "circe-core" % "0.9.3",
"io.circe" %% "circe-generic" % "0.9.3",
"io.circe" %% "circe-parser" % "0.9.3"
)
Теперь давайте определим наши классы и сериализуем + десериализовать их:
sealed trait Thing
case class SomeThing() extends Thing
case class OtherThing() extends Thing
import io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
val thing: Thing = SomeThing()
// serialize Thing to json
val jsString: String = thing.asJson.spaces2
println(s"serialized $thing to:\n$jsString")
/* serialized SomeThing() to:
{
"SomeThing" : {
}
}
*/
// deserialize json to Thing
val errorOrMyTrait: Either[io.circe.Error, Thing] = for {
json <- parse(jsString) // either ADT, since this may not be a legal json
myDecodedClass <- json.as[Thing] // ADT, since this may be a json that is not in Thing Format
} yield myDecodedClass
println(errorOrMyTrait) // Right(SomeThing())
Обратите внимание, что теперь сериализованный json содержит тип запечатанного класса