Using circe, it's is easy to decode Json in case classes :
import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
case class Bar(xs: List[String])
scala> decode[Bar]("{\"xs\":[\"a\",\"b\"]}")
res2: Either[io.circe.Error,Bar] = Right(Bar(List(a, b)))
scala> decode[Bar]("{\"xs\":[\"a\",\"b\"],\"addedField\":true}")
res3: Either[io.circe.Error,Bar] = Right(Bar(List(a, b)))
But I can see a way to check if all the fields have been used and mapped in the result.
Currently, one the way to check if some information as been lost is the retransform the result in json and diff the jsons (with Json4)
scala> val Diff(_,_,removed) = parse(input) diff parse(result.asJson.noSpaces)
removed: org.json4s.JsonAST.JValue = JObject(List((addedField,JBool(true))))
val noLoss = removed == JNothing
Is there a way to that directly in circe ?
Main problem here, that there is not clear way to determine whether field is consumed by your decoder.
If we'll try to define some notion of such consumption, working as expected for
case class
es:we can now represent some remainder catcher wrapper and corresponding decoder:
having this you can try to extract remaning fields: