Skip to content

Instantly share code, notes, and snippets.

@n4to4
Last active August 2, 2019 11:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save n4to4/3f7dbea65a6c1d6fc6aa84dcac0cf0a8 to your computer and use it in GitHub Desktop.
Save n4to4/3f7dbea65a6c1d6fc6aa84dcac0cf0a8 to your computer and use it in GitHub Desktop.
coproduct json = circe + shapeless
// https://stackoverflow.com/questions/44309520/my-coproduct-encoding-is-ambiguous
import io.circe._, io.circe.generic.semiauto._
import io.circe.shapes._, io.circe.syntax._
import shapeless._, shapeless.union._, shapeless.syntax.singleton._
object Main extends App {
object model {
case class A(a: String)
case class B(a: String, i: Int)
case class C(i: Int, b: Boolean)
implicit val encodeA: Encoder[A] = deriveEncoder
implicit val encodeB: Encoder[B] = deriveEncoder
implicit val encodeC: Encoder[C] = deriveEncoder
implicit val decodeA: Decoder[A] = deriveDecoder
implicit val decodeB: Decoder[B] = deriveDecoder
implicit val decodeC: Decoder[C] = deriveDecoder
}
import model._
type ABC = A :+: B :+: C :+: CNil
val c: ABC = Coproduct[ABC](C(123, false))
//println(c) // Inr(Inr(Inl(C(123,false))))
assert { c.asJson.noSpaces == """{"i":123,"b":false}""" }
val b: ABC = Coproduct[ABC](B("xyz", 123))
val json = b.asJson
assert { json.noSpaces == """{"a":"xyz","i":123}""" }
val decoded = io.circe.jawn.decode[ABC](json.noSpaces)
assert { decoded == Right(Coproduct[ABC](A("xyz"))) }
assert { ("xyz" :: List(1, 2, 3) :: false :: HNil).asJson.noSpaces == """["xyz",[1,2,3],false]""" }
type ABCL = Union.`'A -> A, 'B -> B, 'C -> C`.T
val bL: ABCL = Coproduct[ABCL]('B ->> B("xyz", 123))
val jsonL = bL.asJson.noSpaces
assert { jsonL == """{"B":{"a":"xyz","i":123}}""" }
val decodedL = io.circe.jawn.decode[ABCL](jsonL)
assert { decodedL == Right(b) }
assert { decodedL == Right(bL) }
val x = ('a ->> "xyz" :: 'b ->> List(1) :: 'c ->> false :: HNil).asJson.noSpaces
assert { x == """{"c":false,"b":[1],"a":"xyz"}""" }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment