Skip to content

Instantly share code, notes, and snippets.

@blvp
Last active October 12, 2018 14:22
Show Gist options
  • Select an option

  • Save blvp/7286395f6e4c1d13c7e3263a67a5f878 to your computer and use it in GitHub Desktop.

Select an option

Save blvp/7286395f6e4c1d13c7e3263a67a5f878 to your computer and use it in GitHub Desktop.
package com.jiwire.pca.tasks.output.views
import mist.api.data.{JsData, JsList, JsMap, JsString}
import mist.api.encoding.JsEncoder
import shadedshapeless._
import shadedshapeless.labelled.FieldType
import shadedshapeless.ops.hlist.{Mapper, ToTraversable}
import shadedshapeless.ops.record._
case class Sheet(
name: String,
columns: Seq[String],
rows: Seq[Seq[JsData]]
)
trait ToRow[A] {
type Out
def apply(a: A): Out
}
object ToRow {
type Aux[A, Out0] = ToRow[A] {
type Out = Out0
}
implicit val hnilToTab: Aux[HNil, HNil] = new ToRow[HNil] {
type Out = HNil
override def apply(a: HNil): HNil = HNil
}
implicit def hlistToTab[H, T <: HList, O <: HList](
implicit headEnc: JsEncoder[H],
toRow: ToRow.Aux[T, O]
): Aux[H :: T, JsData :: O] =
new ToRow[H :: T] {
type Out = JsData :: O
def apply(a: H :: T): JsData :: O = {
headEnc.apply(a.head) :: toRow.apply(a.tail)
}
}
}
trait ToColumns[A] {
def apply(): Seq[String]
}
object ToColumns {
implicit def keysToCols[A, Repr <: HList, KeysRepr <: HList, O <: HList](implicit
labGen: LabelledGeneric.Aux[A, Repr],
keys: Keys.Aux[Repr, KeysRepr],
traversable: ToTraversable.Aux[KeysRepr, List, Symbol]
): ToColumns[A] = new ToColumns[A] {
override def apply(): Seq[String] = {
traversable(keys.apply()).map(_.name)
}
}
}
trait ToSheet[A] {
def apply(name: String, as: Seq[A]): Sheet
}
object ToSheet {
implicit def labGenToSheet[A, H <: HList, F <: HList, O <: HList, Repr <: HList, KeysRepr <: HList, O2<: HList](implicit
gen: Generic.Aux[A, H],
toRow: ToRow.Aux[H, O],
toCols: ToColumns[A],
toList: ToTraversable.Aux[O, List, JsData]
): ToSheet[A] = new ToSheet[A] {
override def apply(name: String, as: Seq[A]): Sheet = {
val rows = as.map(a => toList.apply(toRow.apply(gen.to(a))))
Sheet(name, toCols.apply(), rows)
}
}
def apply[A](implicit toSheet: ToSheet[A]): ToSheet[A] = toSheet
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment