diff --git a/examples/csv/Parser/CSV.roc b/examples/csv/Parser/CSV.roc index 9eba491689..b793e6d08b 100644 --- a/examples/csv/Parser/CSV.roc +++ b/examples/csv/Parser/CSV.roc @@ -1,5 +1,8 @@ interface Parser.CSV exposes [ + CSV, + file, + record ] imports [ Parser.Core.{Parser, fail, const, alt, map, map2, apply, many, oneorMore, sepBy1, between, ignore}, @@ -16,10 +19,19 @@ CSVField : RawStr CSVRecord : List CSVField CSV : List CSVRecord +file : Parser RawStr CSV file = many recordNewline + +recordNewline : Parser RawStr CSVRecord recordNewline = map2 record crlf (\rec, _ -> rec) + +record : Parser RawStr CSVRecord record = sepBy1 field comma + +field : Parser RawStr CSVField field = alt escapedField nonescapedField + +escapedField : Parser RawStr CSVField escapedField = between (many escapedContents) dquote dquote escapedContents = oneOf [ twodquotes |> map (\_ -> 34), # An escaped double quote @@ -29,6 +41,8 @@ escapedContents = oneOf [ textdata ] twodquotes = string "\"\"" + +nonescapedField : Parser RawStr CSVField nonescapedField = many textdata comma = codepoint 44 # ',' cr = codepoint 13 # '\r' diff --git a/examples/csv/main.roc b/examples/csv/main.roc index 51c7605b5e..f024bd0b3f 100644 --- a/examples/csv/main.roc +++ b/examples/csv/main.roc @@ -1,6 +1,6 @@ app "main" packages { pf: "platform/main.roc" } - imports [Parser.Core.{Parser}, Parser.Str.{RawStr}] + imports [Parser.Core.{Parser}, Parser.Str.{RawStr}, Parser.CSV.{CSV}] provides [main] to pf # Until issue https://github.com/rtfeldman/roc/issues/3438 is fixed, @@ -8,12 +8,12 @@ app "main" # with hard-coded input. main : Str -main = fullTest myparser "[10,20,30,40,50,60,1234,1337,101010101]" +main = fullTest myparser "10,20\r\n30,40\r\n" partialTest = \parser, input -> when Parser.Str.runPartialStr parser input is Ok result -> - val = result.val |> Str.joinWith(" -- ") + val = result.val |> Str.joinWith("\r\n") # val = result.val leftover = result.input "Parse success: \(val) (leftover string: \(leftover))\n" @@ -24,7 +24,7 @@ fullTest = \parser, input -> when Parser.Str.runStr parser input is Ok result -> # val = result |> Str.joinWith(", ") - val = result |> Str.joinWith(" -- ") + val = result |> Str.joinWith("\r\n") # val = result "Parse success: \(val)\n" Err (ParsingFailure problem) -> @@ -34,7 +34,13 @@ fullTest = \parser, input -> myparser : Parser RawStr (List Str) myparser = - Parser.Str.digits - |> Parser.Core.map Num.toStr - |> Parser.Core.sepBy1 (Parser.Str.scalar ',') - |> Parser.Core.between (Parser.Str.scalar '[') (Parser.Str.scalar ']') + Parser.CSV.file + |> Parser.Core.map \records -> + records + |> List.map (\record -> + record + |> List.map (\field -> + field + |> Str.fromUtf8 + |> Result.withDefault "Unexpected problem while turning a List U8 back into a Str") + |> Str.joinWith ", ")