]> gitweb @ CieloNegro.org - task-reporter.git/blob - src/main/scala/jp/ymir/taskReporter/core/TSV.scala
new tsv
[task-reporter.git] / src / main / scala / jp / ymir / taskReporter / core / TSV.scala
1 package jp.ymir.taskReporter.core
2 import scala.collection._
3 import scala.collection.immutable.StringLike
4
5 object TSV {
6   type Header = Seq[Symbol]
7   type Field  = String
8   type Record = Map[Symbol, Field]
9
10   def decode[A: FromRecord](tsv: StringLike[_]): Seq[A] = {
11     val lines  = tsv.split('\n').filter(!_.isEmpty)
12     val header = lines.head.split('\t').map(Symbol(_))
13     val body   = lines.tail.map(line => (header zip line.split('\t')).toMap)
14     return body.map(implicitly[FromRecord[A]].parseRecord)
15   }
16
17   trait FromRecord[A] {
18     def parseRecord(r: Record): A
19   }
20
21   trait FromField[A] {
22     def parseField(f: Field): A
23   }
24   def parseField[A: FromField](f: Field): A
25     = implicitly[FromField[A]].parseField(f)
26
27   trait ToRecord[A] {
28     def toRecord(a: A): Record
29   }
30
31   trait ToField[A] {
32     def toField(a: A): Field
33   }
34
35   // Option[A]
36   implicit def OptionFromField[A: FromField] = new FromField[Option[A]] {
37     def parseField(f: Field): Option[A] = {
38       if (f.isEmpty) {
39         return None
40       }
41       else {
42         return Some(implicitly[FromField[A]].parseField(f))
43       }
44     }
45   }
46
47   // String
48   implicit def StringFromField = new FromField[String] {
49     def parseField(f: Field): String = f
50   }
51
52   // Int
53   implicit def IntFromField = new FromField[Int] {
54     def parseField(f: Field): Int = f.toInt
55   }
56 }