Skip to content

Instantly share code, notes, and snippets.

@n4to4
Created August 29, 2016 06:44
Show Gist options
  • Save n4to4/e5bf1b4cf26563162b23a8990a3110c7 to your computer and use it in GitHub Desktop.
Save n4to4/e5bf1b4cf26563162b23a8990a3110c7 to your computer and use it in GitHub Desktop.
Decoding JSON into Shapeless's sized collections in Scala with circe:
// http://stackoverflow.com/questions/39183041/circe-type-level-json-a-function/39183581#39183581
// https://twitter.com/travisbrown/status/769579633771773954
object Main extends App {
import cats.data.Xor
import io.circe.{Decoder, DecodingFailure}
import shapeless.{Nat, Sized}
import shapeless.ops.nat.ToInt
import shapeless.syntax.sized._
implicit def decodeSized[L <: Nat, A](implicit
dl: Decoder[List[A]],
ti: ToInt[L]
): Decoder[Sized[List[A], L]] = Decoder.instance { c =>
dl(c).flatMap(as =>
Xor.fromOption(as.sized[L], DecodingFailure(s"Sized[List[A], _${ti()}]", c.history))
)
}
case class SSN(value: Sized[List[Int], Nat._8])
implicit val decodeSSN: Decoder[SSN] = Decoder[Sized[List[Int], Nat._8]].map(SSN(_))
import io.circe.jawn.decode
val x = decode[SSN]("[1, 2, 3, 4, 5, 6, 7, 8]")
println(x)
val y = decode[SSN]("[1, 2, 3, 4, 5, 6, 7]")
println(y)
// Right(SSN(List(1, 2, 3, 4, 5, 6, 7, 8)))
// Left(DecodingFailure(Sized[List[A], _8], List()))
}
/*
libraryDependencies ++= Seq(
"org.typelevel" %% "cats" % "0.7.0",
"com.chuusai" %% "shapeless" % "2.3.2"
)
val circeVersion = "0.5.0-M3"
libraryDependencies ++= Seq(
"io.circe" %% "circe-core",
"io.circe" %% "circe-generic",
"io.circe" %% "circe-parser",
"io.circe" %% "circe-literal"
).map(_ % circeVersion)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment