module CSV.Parse
( parse
) where
import qualified Data.Attoparsec.Text as A
import qualified Data.Text as Text
import Control.Applicative
import CSV.Types
parse :: Text.Text -> CSV SQLVal
parse text =
case A.parseOnly csvParser text of
Left s -> error s
Right c -> c
csvParser :: A.Parser (CSV SQLVal)
csvParser = do
rows <- A.sepBy1 rowParser (A.skip A.isEndOfLine)
return (CSV rows)
rowParser :: A.Parser [SQLVal]
rowParser = A.sepBy1 elementParser $ A.string ", "
elementParser :: A.Parser SQLVal
elementParser =
I <$> A.decimal
<|> do
text <- A.many1 $
textParser
<|> quotationParser
return (NVar $ Text.concat text)
textParser :: A.Parser Text.Text
textParser = A.takeWhile1 (A.notInClass [',','\n', '"'])
quotationParser :: A.Parser Text.Text
quotationParser =
let quote = '"' in
let f q1 t q2 = Text.cons q1 (Text.snoc t q2) in
f <$> A.char quote <*>
quotedString [quote] <*>
A.char quote
quotedString :: String -> A.Parser Text.Text
quotedString quote = A.takeWhile (A.notInClass quote)