与@SomeName 创建的方法类似,但解码器不需要HCursor:
sealed trait Value
object Value {
final case class Values(id: Int, text: String) extends Value
final case class IntValue(i: Int) extends Value
final case class StringValue(s: String) extends Value
implicit val valueDecoder: Decoder[Value] = Decoder[String]
.map[Value](StringValue)
.or(Decoder[Int].map[Value](IntValue))
.or(Decoder.forProduct2("id", "text")(Values.apply).map[Value](identity))
}
以及封闭对象:
final case class Example(field1: Int, value: Value)
object Example {
implicit val exampDecoder: Decoder[Example] =
Decoder.forProduct2("field1", "value")(Example.apply)
}
运行它:
import io.circe.Decoder
import io.circe.parser._
def main(args: Array[String]): Unit = {
val fst =
"""
|{
| "field1": 32,
| "value": {
| "id": 23,
| "text": "text"
| }
|}""".stripMargin
val snd =
"""
|{
| "field1": 32,
| "value": 21
|}
|""".stripMargin
val third =
"""{
| "field1": 32,
| "value": "value"
|}
|""".stripMargin
println(decode[Example](fst))
println(decode[Example](snd))
println(decode[Example](third))
}
结果:
Right(Example(32,Values(23,text)))
Right(Example(32,IntValue(21)))
Right(Example(32,StringValue(value)))