Pascal case transform for discriminator parsing to enum cases

71 views Asked by At

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?

1

There are 1 answers

1
Matt Bovel On BEST ANSWER

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).