Skip to content

Instantly share code, notes, and snippets.

@melrief
Created January 5, 2015 21:17
Show Gist options
  • Save melrief/b0ba397615f1d9983094 to your computer and use it in GitHub Desktop.
Save melrief/b0ba397615f1d9983094 to your computer and use it in GitHub Desktop.
package csvShapeless
import shapeless._, labelled.{ field, FieldType }, syntax.singleton._
import scala.util.{Try,Success,Failure}
case class Person(name: String, surname: String, age: Int)
object Main extends App {
import CSVConverter._
val hListConverter = CSVConverter[String :: String :: Int :: HNil]
println(hListConverter.from("mario,pastorelli,28")) // works
// val converter = CSVConverter[Person] // doesn't because Coproduct is missing
}
class CSVException(s: String) extends RuntimeException
trait CSVConverter[T] {
def from(s: String): Try[T]
def to(t: T): String
}
object CSVConverter {
def apply[T](implicit st: Lazy[CSVConverter[T]]): CSVConverter[T] = st.value
def fail(s: String) = Failure(new CSVException(s))
// Primitives
implicit def stringCSVConverter: CSVConverter[String] = new CSVConverter[String] {
def from(s: String): Try[String] = Success(s)
def to(s: String): String = s
}
implicit def intCsvConverter: CSVConverter[Int] = new CSVConverter[Int] {
def from(s: String): Try[Int] = Try(s.toInt)
def to(i: Int): String = i.toString
}
//
implicit def deriveHNil: CSVConverter[HNil] =
new CSVConverter[HNil] {
def from(s: String): Try[HNil] = s match {
case "" => Success(HNil)
case s => fail("Cannot convert " ++ s ++ " to HNil")
}
def to(n: HNil) = ""
}
implicit def deriveHCons[V, T <: HList]
(implicit scv: Lazy[CSVConverter[V]], sct: Lazy[CSVConverter[T]])
: CSVConverter[V :: T] =
new CSVConverter[V :: T] {
def from(s: String): Try[V :: T] = s.span(_ != ',') match {
case (before,after) =>
for {
front <- scv.value.from(before)
back <- sct.value.from(if (after.isEmpty) after else after.tail)
} yield front :: back
case _ => fail("Product miss = " ++ s)
}
def to(ft: V :: T): String = {
scv.value.to(ft.head) ++ "," ++ sct.value.to(ft.tail)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment