frees-io/freestyle-cassandra

Update FieldLister to use an implicit Printer

Closed this issue · 0 comments

A Printer is just a trait that transforms a String into a String, as shown here:

trait Printer {
def print(name: String): String
}

We currently have a FieldLister that provides a way to list the column names for a case class:

trait FieldLister[A] {
val list: List[String]
}

We need to refactor it to make use of an implicit Printer instead of using the actual case class field name here:

FieldLister[FieldType[K, H] :: T](witness.value.name :: tLister.list)

We also need to adapt Unit Tests to this new implementation. The tests are located here:

"insert" should {
"generate a right statement for a regular case class" in {
import FieldLister._
StatementGenerator[A].insert("A") shouldBe "INSERT INTO A (a1,a2,a3) VALUES (?,?,?)"
}
"generate a right statement for a case class with another embedded case class" in {
import FieldLister._
StatementGenerator[C].insert("C") shouldBe "INSERT INTO C (c1,c2) VALUES (?,?)"
}
"generate a right expanded statement for a case class with another embedded case class" in {
import StatementGenerator._
import FieldListerExpanded._
StatementGenerator[C].insert("C") shouldBe "INSERT INTO C (c1,b1,b2) VALUES (?,?,?)"
}
}
"select" should {
"generate a right statement for a regular case class" in {
import FieldLister._
StatementGenerator[A].select("A") shouldBe "SELECT a1,a2,a3 FROM A"
}
"generate a right statement for a case class with another embedded case class" in {
import FieldLister._
StatementGenerator[C].select("C") shouldBe "SELECT c1,c2 FROM C"
}
"generate a right expanded statement for a case class with another embedded case class" in {
import FieldListerExpanded._
StatementGenerator[C].select("C") shouldBe "SELECT c1,b1,b2 FROM C"
}
}

An example of the behavior we are looking for can be found here:

implicit def hconsFromReader[K <: Symbol, V, L <: HList](
implicit
witness: Witness.Aux[K],
codec: ByteBufferCodec[V],
grT: FromReader[L],
printer: Printer): FromReader[FieldType[K, V] :: L] =
new FromReader[FieldType[K, V] :: L] {
override def apply[M[_]](reader: ByteBufferReader)(
implicit ME: MonadError[M, Throwable]): M[FieldType[K, V] :: L] = {
val newName = printer.print(witness.value.name)
ME.flatMap(reader.read(newName)) { byteBuffer =>
ME.map2(codec.deserialize(byteBuffer), grT(reader)) {
case (result, l) => new FieldBuilder[K].apply(result) :: l
}
}
}
}