Skip to content

Instantly share code, notes, and snippets.

@deusaquilus
Last active January 15, 2020 08:44
Show Gist options
  • Save deusaquilus/d4a707e1a9de86aa1fe14399b4e5435b to your computer and use it in GitHub Desktop.
Save deusaquilus/d4a707e1a9de86aa1fe14399b4e5435b to your computer and use it in GitHub Desktop.
Matching MirroredElemLabels and MirroredElemTypes at the same time
trait FieldCollector[T] {
def collect(fields: Collector): Collector
}
object FieldCollector {
inline def collectFromChild[T](fields: ArrayBuffer[String]): Collector =
summonFrom {
case fc: FieldCollector[T] => fc.collect(fields)
}
inline def collectFromProduct[Fields <: Tuple, Types <: Tuple](fields: ArrayBuffer[String]): ArrayBuffer[String] = {
inline erasedValue[(Fields, Types)] match {
case (_: (field *: fields), _: (tpe *: types)) =>
collectFromProduct[fields, types](fields.add(constValue[field].toString))
case _ =>
fields
}
}
inline def derived[T](given ev: Mirror.Of[T], ct: ClassTag[T]): FieldCollector[T] = new FieldCollector[T] {
def collect(fields: ArrayBuffer[String]): ArrayBuffer[String] = {
inline ev match {
case m: Mirror.ProductOf[T] =>
collectFromProduct[m.MirroredElemLabels, m.MirroredElemTypes](fields)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment