Elm 界隈では構文解析するライブラリを「パーサー(Parser)」、それを Elm の型に落とし込むものを「デコーダー(Decoder)」と呼び分けることが多い。パーサーは既にあって(lovasoa/elm-csv)、デコーダーで良いものがなかったので作った。
CsvDecode - elm-csv-decode 1.0.0
使い方
elm-tools/parser インスパイアのパイプライン式。
-- CSV の各行をこの User 型にしたい type alias User = { id : String , name : String , age : Int , mail : Maybe String } -- デコーダー Decoder User を作る userDecoder : Decoder User userDecoder = succeed User |= field "id" |= field "name" |= int (field "age") |= optional (field "mail") -- デコードしたい CSV を用意 source : String source = """ id,name,age,mail 1,John Smith,20,john@example.com 2,Jane Smith,19, """ -- 実行 > CsvDecode.run userDecoder source Ok [ { id = "1", name = "John Smith", age = 20, mail = Just "john@example.com" } , { id = "2", name = "Jane Smith", age = 19, mail = Nothing } ]
API 一覧
型を見るだけで使い方が本当に分かるのか実験。
-- Types type Decoder a type alias Options = { separator : String, noHeader : Bool } -- Primitives succeed : a -> Decoder a fail : String -> Decoder a field : String -> Decoder String index : Int -> Decoder String fieldsAfter : String -> Decoder (Dict String String) fieldsBetween : String -> String -> Decoder (Dict String String) -- Convertion int : Decoder String -> Decoder Int float : Decoder String -> Decoder Float string : Decoder String -> Decoder String optional : Decoder a -> Decoder (Maybe a) -- Transform (|=) : Decoder (a -> b) -> Decoder a -> Decoder b map : (a -> b) -> Decoder a -> Decoder b andThen : (a -> Decoder b) -> Decoder a -> Decoder b -- Run run : Decoder a -> String -> Result String (List a) runWithOptions : Options -> Decoder a -> String -> Result String (List a) runAll : Decoder a -> String -> (List a, List String) runAllWithOptions : Options -> Decoder a -> String -> (List a, List String) defaultOptions : Options
分からないと思うのでドキュメント読んでください。
苦労した点
空文字の扱い。要するに foo,,bar
の2列目。特に optional
を使った時に、数値だと Nothing
なのに文字列だと Just ""
になるのは微妙なので、デフォルトで空文字は null 扱いにして string
と指定した場合のみ値が存在することにした。
ソース
割ときれいに書けたかもしれない。
elm-test は最近のアップデートでトップレベルに Test 型の関数を置くだけで勝手に実行してくれるようになった。便利。