jsonscalacircegeneric-derivation

Is that possible to make semiauto decoders consider default values for case class fields?


Is that possible to make semiauto decoders consider default values for case class fields?

The following code will fail with:

Left(DecodingFailure(Attempt to decode value on failed cursor, List(DownField(isActive))))

I thought circe would consider the default value for the case class field isActive

case class Person(
  id: Option[Int] = None,
  name: String,
  isActive: Boolean = true
)

implicit val personJsonDecoder: Decoder[Person] = deriveDecoder

val rawJson = """
{
  "name": "Geovanny Junio"
}
"""

val r = for {
  j <- parse(rawJson)
  p <- j.as[Person]
} yield p

println(r)

Solution

  • Yes, but you'll need circe-generic-extras:

    import io.circe.Decoder
    import io.circe.generic.extras.Configuration
    import io.circe.generic.extras.semiauto.deriveDecoder
    
    case class Person(
      id: Option[Int] = None,
      name: String,
      isActive: Boolean = true
    )
    
    object Person {
      implicit val personConfig: Configuration =
        Configuration.default.withDefaults
      implicit val personJsonDecoder: Decoder[Person] = deriveDecoder
    }
    

    And then:

    scala> io.circe.jawn.decode[Person]("""{"name": "Geovanny Junio"}""")
    res0: Either[io.circe.Error,Person] = Right(Person(None,Geovanny Junio,true))
    

    I've been intending to add this functionality to circe-derivation, but haven't had time, so circe-generic-extras is the only way to make it work for now (short of writing your own decoder).