| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
Circuit.Parser.Csv
Description
CSV for the circuits ecosystem: RFC 4180 on Circuit.Parser combinators.
Where Circuit.Parser.Json skips whitespace, csv skips nothing — spaces are data, line endings are structure. The dialect:
- line endings lenient:
\r\n|\n|\r. - quoting strict:
"opens a quoted field only at field start; inside a quoted field""is an escaped quote; after the closing quote only,, EOL, or EOF may follow. A bare"inside a plain field is rejected. - a trailing comma is a field:
a,b,is three fields. An empty line is one record of one empty field. The final record may omit its line ending. Empty input is zero records. - field-count consistency across records is not checked — consumer policy, like duplicate keys in json.
The table
A CSV table: rows of fields, source order. No header policy — headers are a consumer convention, not a parsing fact.
Parsing
record :: Parser Identity ByteString Char [Text] Source #
Parse one record: fields separated by commas. A trailing comma is a trailing empty field.
field :: Parser Identity ByteString Char Text Source #
Parse one field, quoted or plain. try is load-bearing: without it, a
failed quoted attempt (say, an unterminated quote) would hand the plain
alternative the stream at the point of failure — consumed quote and all —
and an unterminated quote would silently parse as an empty field.
Boundary
decodeCsv :: ByteString -> Either String Csv Source #
Parse a CSV document, rejecting trailing garbage.
>>>decodeCsv (C.pack "a,b\r\nc,d\r\n")Right (Csv [["a","b"],["c","d"]])
>>>decodeCsv (C.pack "name,note\n\"say \"\"hi\"\"\",ok")Right (Csv [["name","note"],["say \"hi\"","ok"]])
>>>decodeCsv (C.pack "a,b,\n")Right (Csv [["a","b",""]])
>>>decodeCsv (C.pack "")Right (Csv [])
>>>decodeCsv (C.pack "a\"b,c")Left "invalid CSV"