Skip to content

Instantly share code, notes, and snippets.

@etorreborre
Forked from markhibberd/argonaut.scala
Last active January 30, 2018 14:48
Show Gist options
  • Save etorreborre/ccecc73df433ecb956d9 to your computer and use it in GitHub Desktop.
Save etorreborre/ccecc73df433ecb956d9 to your computer and use it in GitHub Desktop.
Argonaut union type / inheritance example
package argonaut.example
import argonaut._, Argonaut._
import scalaz._, Scalaz._
object UnionExample extends {
sealed trait Thing
final case class One(n: String, i: Int) extends Thing
final case class Two(n: String) extends Thing
case object Three extends Thing
implicit def ThingEncodeJson: EncodeJson[Thing] =
EncodeJson(_ match {
case One(n, i) => Json("one" := Json("name" := n, "age" := i))
case Two(n) => Json("two" := Json("name" := n))
case Three => Json("three" := ())
})
implicit def ThingDecodeJson: DecodeJson[Thing] =
DecodeJson(c =>
tagged("one", c, jdecode2L(One.apply)("name", "age")) |||
tagged("two", c, jdecode1L(Two.apply)("name")) |||
tagged("three", c, implicitly[DecodeJson[Unit]].map(_ => Three)))
def tagged[A](tag: String, c: HCursor, decoder: DecodeJson[A]): DecodeResult[A] =
(c --\ tag).hcursor.fold(DecodeResult.fail[A]("Invalid tagged type", c.history))(decoder.decode)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment