csv-enumerator 0.9.2.1 → 0.9.3
raw patch · 3 files changed
+104/−39 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.CSV.Enumerator.Parser: csv :: CSVSettings -> Parser [Row]
+ Data.CSV.Enumerator.Parser: parseCSV :: CSVSettings -> ByteString -> Either String [Row]
+ Data.CSV.Enumerator.Parser: parseRow :: CSVSettings -> ByteString -> Either String (Maybe Row)
+ Data.CSV.Enumerator.Parser: row :: CSVSettings -> Parser (Maybe Row)
Files
- csv-enumerator.cabal +2/−1
- src/Data/CSV/Enumerator.hs +2/−38
- src/Data/CSV/Enumerator/Parser.hs +100/−0
csv-enumerator.cabal view
@@ -1,5 +1,5 @@ Name: csv-enumerator-Version: 0.9.2.1+Version: 0.9.3 Synopsis: A flexible, fast, enumerator-based CSV parser library for Haskell. Homepage: http://github.com/ozataman/csv-enumerator License: BSD3@@ -57,6 +57,7 @@ hs-source-dirs: src Exposed-modules: Data.CSV.Enumerator+ Data.CSV.Enumerator.Parser Other-modules: Data.CSV.Enumerator.Types build-depends:
src/Data/CSV/Enumerator.hs view
@@ -72,7 +72,9 @@ import Safe (headMay) import Data.CSV.Enumerator.Types+import Data.CSV.Enumerator.Parser + class CSVeable r where -- | Convert a CSV row into strict ByteString equivalent.@@ -528,42 +530,4 @@ liftIO $ putStrLn ("Error in parsing: " ++ show e) yield Nothing (E.Chunks []) --row :: CSVSettings -> Parser (Maybe Row)-row csvs = csvrow csvs <|> badrow--badrow :: Parser (Maybe Row)-badrow = P.takeWhile (not . C8.isEndOfLine) *> - (C8.endOfLine <|> C8.endOfInput) *> return Nothing--csvrow :: CSVSettings -> Parser (Maybe Row)-csvrow c = - let rowbody = (quotedField' <|> (field c)) `sepBy` C8.char (csvSep c)- properrow = rowbody <* (C8.endOfLine <|> P.endOfInput)- quotedField' = case csvQuoteChar c of- Nothing -> mzero- Just q' -> try (quotedField q')- in do- res <- properrow- return $ Just res--field :: CSVSettings -> Parser Field-field s = P.takeWhile (isFieldChar s) --isFieldChar s = notInClass xs'- where xs = csvSep s : "\n\r"- xs' = case csvQuoteChar s of - Nothing -> xs- Just x -> x : xs--quotedField :: Char -> Parser Field-quotedField c = - let quoted = string dbl *> return c- dbl = B8.pack [c,c]- in do- C8.char c - f <- many (C8.notChar c <|> quoted)- C8.char c - return $ B8.pack f-
+ src/Data/CSV/Enumerator/Parser.hs view
@@ -0,0 +1,100 @@+{-| ++ This module exports the underlying Attoparsec row parser. This is helpful if+ you want to do some ad-hoc CSV string parsing.++-}++module Data.CSV.Enumerator.Parser ++( parseCSV, parseRow, row, csv ) ++where+++import Control.Applicative hiding (many)+import Control.Monad (mzero, mplus, foldM, when, liftM)+import Control.Monad.IO.Class (liftIO, MonadIO)+import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as B8+import Data.ByteString.Char8 (ByteString)+import Data.ByteString.Internal (c2w)+import qualified Data.Map as M++import Data.Attoparsec as P hiding (take)+import qualified Data.Attoparsec.Char8 as C8+import Data.Word (Word8)++import Data.CSV.Enumerator.Types+++------------------------------------------------------------------------------+-- | Try to parse given string as CSV+parseCSV :: CSVSettings -> ByteString -> Either String [Row]+parseCSV s = parseOnly $ csv s+++------------------------------------------------------------------------------+-- | Try to parse given string as 'Row'+parseRow :: CSVSettings -> ByteString -> Either String (Maybe Row)+parseRow s = parseOnly $ row s+++------------------------------------------------------------------------------+-- | Parse CSV+csv :: CSVSettings -> Parser [Row]+csv s = do+ r <- row s+ end <- atEnd+ case end of+ True -> case r of+ Just x -> return [x]+ Nothing -> return []+ False -> do+ rest <- csv s+ return $ case r of+ Just x -> x : rest+ Nothing -> rest+++------------------------------------------------------------------------------+-- | Parse a CSV row+row :: CSVSettings -> Parser (Maybe Row)+row csvs = csvrow csvs <|> badrow+++badrow :: Parser (Maybe Row)+badrow = P.takeWhile (not . C8.isEndOfLine) *> + (C8.endOfLine <|> C8.endOfInput) *> return Nothing++csvrow :: CSVSettings -> Parser (Maybe Row)+csvrow c = + let rowbody = (quotedField' <|> (field c)) `sepBy` C8.char (csvSep c)+ properrow = rowbody <* (C8.endOfLine <|> P.endOfInput)+ quotedField' = case csvQuoteChar c of+ Nothing -> mzero+ Just q' -> try (quotedField q')+ in do+ res <- properrow+ return $ Just res++field :: CSVSettings -> Parser Field+field s = P.takeWhile (isFieldChar s) ++isFieldChar s = notInClass xs'+ where xs = csvSep s : "\n\r"+ xs' = case csvQuoteChar s of + Nothing -> xs+ Just x -> x : xs++quotedField :: Char -> Parser Field+quotedField c = + let quoted = string dbl *> return c+ dbl = B8.pack [c,c]+ in do+ C8.char c + f <- many (C8.notChar c <|> quoted)+ C8.char c + return $ B8.pack f++