Skip to content

Instantly share code, notes, and snippets.

@Eternity-Yarr
Created August 15, 2016 09:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Eternity-Yarr/db3b88cb900c3773689de294b44f35aa to your computer and use it in GitHub Desktop.
Save Eternity-Yarr/db3b88cb900c3773689de294b44f35aa to your computer and use it in GitHub Desktop.
import io.circe.{Decoder, DecodingFailure}
import io.circe.parser._
import io.circe.generic.auto._
import cats.syntax.xor._
object Test extends App {
val unionA = "{\"union\" : { \"a\" : { \"a1\": 1, \"a2\": \"two\" } } }"
val unionB = "{\"union\" : { \"b\" : { \"b1\": \"type\", \"b2\": 2 } } }"
sealed trait JsonUnion
case class typeA(a1: Int, a2: String) extends JsonUnion
case class typeB(b1: String, b2: Int) extends JsonUnion
implicit def decoder: Decoder[JsonUnion] = Decoder.instance[JsonUnion] { c =>
val u = c.downField("union")
Seq(
u.downField("a").cursor.map(_.as[typeA]),
u.downField("b").cursor.map(_.as[typeB])
).collectFirst { case Some(s) => s }
.map(_.right)
.getOrElse(DecodingFailure("invalid union", List.empty).left)
.flatMap(identity)
}
println(decode(unionA))
println(decode(unionB))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment