【作りたいもの】golangでLCSVパーサ

メモ

LCSV (Labeled-CSV) のパーサがほしい できればstruct tagのパースできるやつ

使い方は2種類あって、CSVパーサみたいに各行パースするやつと、JSON的にワンライナーの文字列をパースするやつ。

イメージ(csvと同じ感じで)

values := `name: John, country: US, sex: male
name: Hana, country: JP, sex: female
name: Kim, country: CH`

var datum map[string]string
var err error
reader := lcsv.NewReader(strings.NewReader(values))
for err == nil {
    datum, err = reader.Read()
    fmt.Println(datum)
}
/* Output:
map[name:John country:US sex:male]
map[name:Hana country:JP sex:female]
map[name:Kim country:CH]
*/

イメージ(jsonな使い方)

GoのStruct Tagは、tagName:"HOST_NAME,required,default=example.com"みたいな書かれ方しがち。 tagName をキーに HOST_NAME,required,default=example.com はカンタンに取得できるけど、 中身は各々勝手にルール決めてパースしてる感じ。 でも要はこれLCSVだよねと思うので、”クォーテーションできない(Unquoted)“、”値とラベルの区切り文字が= (LabelSeparator('='))とかオプション指定できれば、json.Decoderみたいにやれそう。

var key string
var options map[string]string
tagValue := `required,default=example.com`
decoder := lcsv.NewDecoder(lcsv.Separator(','), lcsv.Unquoted(), lcsv.LabelSeparator('='))
if err := decoder.Decode(tagValue, options); err != nil {
    panic(err)
}
fmt.Println(options)
/* Output:
map[required: default:example.com]
*/

メンドクサポイント

エスケープシーケンス。 CSVのあれは控えめに言ってうんこだから実装したくない。 \ (backslash) でいいじゃん。