Skip to content

Instantly share code, notes, and snippets.

@taojang
Created June 30, 2015 13:02
Show Gist options
  • Save taojang/f6a9352dbc618039e3a3 to your computer and use it in GitHub Desktop.
Save taojang/f6a9352dbc618039e3a3 to your computer and use it in GitHub Desktop.
import shapeless._
import scala.collection.generic.IsTraversableLike
import scala.util.Try
import scala.util.Success
import scala.language.higherKinds
import scala.language.implicitConversions
// @see https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/csv.scala
case class DateStr(year: String, month: String, day: String) {
override def toString = year + '-' + month + '-' + day
}
class ParserException(s: String) extends RuntimeException
trait BigQueryParser[A, B] {
def parse(s: A): Try[B]
}
object BigQueryParser {
implicit def intBigQueryParser: BigQueryParser[String, Int] = new BigQueryParser[String, Int] {
def parse(s: String) = Try(s.toInt)
}
implicit def strBigQueryParser: BigQueryParser[String, String] = new BigQueryParser[String, String] {
def parse(s: String) = Success(s)
}
implicit def bigDecBigQueryParser: BigQueryParser[String, BigDecimal] = new BigQueryParser[String, BigDecimal] {
def parse(s: String) = Try(BigDecimal(s))
}
implicit def bigIntBigQueryParser: BigQueryParser[String, BigInt] = new BigQueryParser[String, BigInt] {
def parse(s: String) = Try(BigInt(s))
}
implicit def dateBigQueryParser: BigQueryParser[String, DateStr] = new BigQueryParser[String, DateStr] {
def parse(s: String) = Try(DateStr(s.slice(0, 4), s.slice(4, 6), s.slice(6, 9)))
}
implicit def deriveHNil[Repr, L <: _0](implicit itl: IsTraversableLike[Repr]): BigQueryParser[Sized[Repr, L], HNil] = new BigQueryParser[Sized[Repr, L], HNil] {
def parse(s: Sized[Repr, L]) = Success(HNil)
}
implicit def deriveHCons[Repr, L <: Nat, V, T <: HList](implicit itl: IsTraversableLike[Repr], ev: AdditiveCollection[Repr], ts: BigQueryParser[Sized[Repr, L], T], conv: BigQueryParser[IsTraversableLike[Repr]#A, V]): BigQueryParser[Sized[Repr, Succ[L]], V :: T] = new BigQueryParser[Sized[Repr, Succ[L]], V :: T] {
def parse(s: Sized[Repr, Succ[L]]): Try[V :: T] =
for {
h <- conv.parse(s.head)
t <- ts.parse(s.tail)
} yield h :: t
}
implicit def deriveClass[Repr, L <: Nat, A, B](implicit gen: Generic.Aux[A, B], conv: BigQueryParser[Sized[Repr, L], B]): BigQueryParser[Sized[Repr, L], A] = new BigQueryParser[Sized[Repr, L], A] {
def parse(s: Sized[Repr, L]): Try[A] = conv.parse(s).map(gen.from)
}
def apply[A, B](implicit st: BigQueryParser[A, B]): BigQueryParser[A, B] = st
}
object BQTest extends App{
import BigQueryParser._
import nat._
val s: Sized[IndexedSeq[String], nat._3] = Sized("Testing", "2.0", "1")
println(BigQueryParser[String, Int].parse("2"))
//BigQueryParser[Sized[IndexedSeq[String], nat._3], String :: BigDecimal :: BigInt :: HNil].parse(s)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment