Skip to content

Instantly share code, notes, and snippets.

@mtranter
Last active November 19, 2017 21:15
Show Gist options
  • Save mtranter/859a7d10190fe91696287feaedb41915 to your computer and use it in GitHub Desktop.
Save mtranter/859a7d10190fe91696287feaedb41915 to your computer and use it in GitHub Desktop.
Generate Default Case Class instances with HLists
package com.trizzle
import java.util.UUID
import shapeless.{::, Generic, HList, HNil, Lazy}
trait DefaultFor[T] {
val default: T
}
trait LowPriorityDefaults {
def defaultFor[T](t: T) = new DefaultFor[T] {
override val default = t
}
implicit val defaultForString = defaultFor("")
implicit val defaultForInt = defaultFor(0)
implicit val defaultForLong = defaultFor(0L)
implicit val defaultForUUID = defaultFor(UUID.randomUUID())
implicit val defaultForDouble = defaultFor(0d)
implicit val defaultForBool = defaultFor(false)
implicit def defaultForOption[T] = defaultFor[Option[T]](None)
}
object DefaultFor extends LowPriorityDefaults {
def apply[T](implicit cp: Lazy[DefaultFor[T]]) = cp.value.default
implicit def hnilDefault = new DefaultFor[HNil] {
override val default = HNil
}
implicit def hconsDefault[H, T <: HList](implicit headDef: Lazy[DefaultFor[H]], taildDef: Lazy[DefaultFor[T]]) = new DefaultFor[H :: T] {
override val default = {
headDef.value.default :: taildDef.value.default
}
}
implicit def classAuxDefault[T,R](implicit gen: Generic.Aux[T,R], conv: DefaultFor[R]): DefaultFor[T] = new DefaultFor[T] {
override val default = {
gen.from(conv.default)
}
}
}
package com.trizzle
case class Person(id: Long, firstName: String, lastName: String, middleName: Option[String])
object TestDefaults {
val person = DefaultFor[Person] //Person(0,"","",None)
}
object TestOverrides {
//Provides alternative implementation for DefaultFor[Option[T]]
//for all [T] that have a DefaultFor in implicit scope
implicit def defaultForSome[T](implicit df: DefaultFor[T]): DefaultFor[Option[T]] = new DefaultFor[Option[T]] {
override val default = Some(df.default)
}
val person = DefaultFor[Person] //Person(0,"","",Some(""))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment