]> gitweb @ CieloNegro.org - task-reporter.git/blobdiff - src/main/scala/jp/ymir/taskReporter/core/TSV.scala
new tsv
[task-reporter.git] / src / main / scala / jp / ymir / taskReporter / core / TSV.scala
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 (file)
index 0000000..28d9833
--- /dev/null
@@ -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
+  }
+}