Created
January 3, 2014 03:05
-
-
Save markhibberd/8231912 to your computer and use it in GitHub Desktop.
argonaut union type example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
Never mind, it's possible to just widen the type to the common supertype, using another map[T], scalaz widen, or in my case, simple ascription of the supertype to a case object or case class constructor.
(h/t @tpolecat for leading me to the finish line on this one)