Skip to content

Instantly share code, notes, and snippets.

@andresilva
Created September 10, 2013 13:48
Show Gist options
  • Save andresilva/6509656 to your computer and use it in GitHub Desktop.
Save andresilva/6509656 to your computer and use it in GitHub Desktop.
HListDeserializer
import shapeless._
import shapeless.poly._
import shapeless.ops.hlist._
import scala.util.Try
trait Deserializer[A, B] {
def apply(t: A): Either[String, B]
}
object Deserializer {
implicit def identity[A] = new Deserializer[A, A] {
def apply(t: A) = Right(t)
}
implicit def stringToInt = new Deserializer[String, Int] {
def apply(s: String) = try Right(s.toInt) catch { case _ => Left("error") }
}
}
trait DeserializeTo[In <: HList, Out <: HList] {
def apply(l: In): Out
}
object DeserializeTo {
private class BubbleLeftException(val left: Left[Any, Any]) extends RuntimeException
implicit def hnilDeserializer: DeserializeTo[HNil, HNil] =
new DeserializeTo[HNil, HNil] {
def apply(l: HNil) = HNil
}
implicit def hlistDeserializer[InH, InT <: HList, OutH, OutT <: HList](implicit des: Deserializer[InH, OutH], dt: DeserializeTo[InT, OutT]) =
new DeserializeTo[InH :: InT, OutH :: OutT] {
def apply(l: InH :: InT) = des(l.head) match {
case Right(x) => x :: dt(l.tail)
case left: Left[_, _] => throw new BubbleLeftException(left)
}
}
}
case class HListDeserializer[T](implicit gen: Generic[T] { type Repr <: HList }) {
def apply[L <: HList](l: L)(implicit des: DeserializeTo[L, gen.Repr]) = gen.from(des(l))
}
case class Foo(i1: Int, i2: Int)
val des = HListDeserializer[Foo]
des(1 :: 2 :: HNil)
// <console>:31: error: could not find implicit value for parameter des: DeserializeTo[shapeless.::[Int,shapeless.::[Int,shapeless.HNil]],des.gen.Repr]
// des(1 :: 2 :: HNil)
// ^
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment