X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=task-reporter.git;a=blobdiff_plain;f=src%2Fmain%2Fscala%2Fjp%2Fymir%2FtaskReporter%2Fcore%2FTSV.scala;fp=src%2Fmain%2Fscala%2Fjp%2Fymir%2FtaskReporter%2Fcore%2FTSV.scala;h=28d9833ad828817d390ac2dacff1eae45edde8ea;hp=0000000000000000000000000000000000000000;hb=cb226bf20b21a6ebc1213152f96e7bcd465cda9d;hpb=f6a51dbcc510104994344140fccdeaab459eb570 diff --git a/src/main/scala/jp/ymir/taskReporter/core/TSV.scala b/src/main/scala/jp/ymir/taskReporter/core/TSV.scala new file mode 100644 index 0000000..28d9833 --- /dev/null +++ b/src/main/scala/jp/ymir/taskReporter/core/TSV.scala @@ -0,0 +1,56 @@ +package jp.ymir.taskReporter.core +import scala.collection._ +import scala.collection.immutable.StringLike + +object TSV { + type Header = Seq[Symbol] + type Field = String + type Record = Map[Symbol, Field] + + def decode[A: FromRecord](tsv: StringLike[_]): Seq[A] = { + val lines = tsv.split('\n').filter(!_.isEmpty) + val header = lines.head.split('\t').map(Symbol(_)) + val body = lines.tail.map(line => (header zip line.split('\t')).toMap) + return body.map(implicitly[FromRecord[A]].parseRecord) + } + + trait FromRecord[A] { + def parseRecord(r: Record): A + } + + trait FromField[A] { + def parseField(f: Field): A + } + def parseField[A: FromField](f: Field): A + = implicitly[FromField[A]].parseField(f) + + trait ToRecord[A] { + def toRecord(a: A): Record + } + + trait ToField[A] { + def toField(a: A): Field + } + + // Option[A] + implicit def OptionFromField[A: FromField] = new FromField[Option[A]] { + def parseField(f: Field): Option[A] = { + if (f.isEmpty) { + return None + } + else { + return Some(implicitly[FromField[A]].parseField(f)) + } + } + } + + // String + implicit def StringFromField = new FromField[String] { + def parseField(f: Field): String = f + } + + // Int + implicit def IntFromField = new FromField[Int] { + def parseField(f: Field): Int = f.toInt + } +}