I have the following JSON:
[{"type": "first_variant", ...}, {"type": "second_variant", ...}]
And I want to parse this JSON to an array of Variant
enums like this:
enum Variant:
case FirstVariant(...)
case SecondVariant(...)
How can I do it with circe
?
In Scala 3 and Circe 0.14.6, you can require a discriminator field in snake case by providing the appropriate Configuration
and Codec
:
//> using lib io.circe::circe-core:0.14.6
//> using lib io.circe::circe-generic:0.14.6
import io.circe.Codec
import io.circe.syntax.EncoderOps
import io.circe.derivation.Configuration
import io.circe.generic.auto.given
enum Variant:
case FirstVariant(x: Int)
case SecondVariant(y: String)
given Configuration =
Configuration
.default
.withDiscriminator("type")
.withSnakeCaseConstructorNames
given Codec[Variant] =
Codec.AsObject.derivedConfigured
@main def example =
val l = List(
Variant.FirstVariant(1),
Variant.SecondVariant("hello")
)
val lJson = l.asJson
println(lJson)
val l2 = lJson.as[List[Variant]].toOption.get
assert(l2 == l)
This outputs:
[
{
"x" : 1,
"type" : "first_variant"
},
{
"y" : "hello",
"type" : "second_variant"
}
]
References: I derived this example from the (outdated) Circle documentation on ADTs, the answer to a similar question for Circe 0.7.0 and the source code of Circe 0.14.6 (Configuration.scala
and ConfiguredDerivesSuite.scala
).