Last active
November 19, 2017 21:15
-
-
Save mtranter/859a7d10190fe91696287feaedb41915 to your computer and use it in GitHub Desktop.
Generate Default Case Class instances with HLists
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 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) | |
} | |
} | |
} |
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 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