Skip to content

Instantly share code, notes, and snippets.

@wfaler
Created June 20, 2016 17:01
Show Gist options
  • Save wfaler/fca88e6346a6893bbb2c1ac41c52c467 to your computer and use it in GitHub Desktop.
Save wfaler/fca88e6346a6893bbb2c1ac41c52c467 to your computer and use it in GitHub Desktop.
case class Foo(bar: String, baz: Int, quux: Boolean)
import shapeless._, labelled.FieldType, record._
trait ToLabels[L <: HList] {
def apply(l: L): List[String]
}
trait LowPriorityToLabels {
implicit def hconsToLabels[K <: Symbol, V, T <: HList](implicit
wit: Witness.Aux[K],
toLabels: ToLabels[T]
): ToLabels[FieldType[K, V] :: T] = new ToLabels[FieldType[K, V] :: T] {
def apply(l: FieldType[K, V] :: T): List[String] =
List(wit.value.name) ++ toLabels(l.tail)
}
}
object ToLabels extends LowPriorityToLabels {
implicit val hnilToLabels: ToLabels[HNil] = new ToLabels[HNil] {
def apply(l: HNil): List[String] = Nil
}
implicit def hconsToLabels0[K <: Symbol, V, R <: HList, T <: HList](implicit
wit: Witness.Aux[K],
gen: LabelledGeneric.Aux[V, R],
toLabelsR: ToLabels[R],
toLabelsT: ToLabels[T]
): ToLabels[FieldType[K, V] :: T] = new ToLabels[FieldType[K, V] :: T] {
def apply(l: FieldType[K, V] :: T): List[String] =
List(wit.value.name) ++ toLabelsT(l.tail)
}
}
implicit class ToLabelOps[A](val a: A) extends AnyVal {
def toLabels[L <: HList](implicit
gen: LabelledGeneric.Aux[A, L],
tmr: ToLabels[L]
): List[String] = tmr(gen.to(a))
}
println(Foo("s",1,true).toLabels)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment