{-# LANGUAGE BangPatterns, CPP, DeriveFunctor, ScopedTypeVariables #-}
module Data.Csv.Incremental
(
HeaderParser(..)
, decodeHeader
, decodeHeaderWith
, Parser(..)
, HasHeader(..)
, decode
, decodeWith
, decodeWithP
, decodeByName
, decodeByNameWith
, decodeByNameWithP
, encode
, encodeWith
, encodeRecord
, Builder
, encodeByName
, encodeDefaultOrderedByName
, encodeByNameWith
, encodeDefaultOrderedByNameWith
, encodeNamedRecord
, NamedBuilder
) where
import Control.Applicative ((<|>))
import qualified Data.Attoparsec.ByteString as A
import Data.Attoparsec.ByteString.Char8 (endOfInput)
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as Builder
import qualified Data.ByteString.Lazy as L
import Data.Semigroup as Semi (Semigroup, (<>))
import qualified Data.Vector as V
import Data.Word (Word8)
import Data.Csv.Conversion hiding (Parser, header, namedRecord, record,
toNamedRecord)
import qualified Data.Csv.Conversion as Conversion
import qualified Data.Csv.Encoding as Encoding
import Data.Csv.Encoding (EncodeOptions(..), Quoting(..), recordSep)
import Data.Csv.Parser
import Data.Csv.Types
import Data.Csv.Util (endOfLine)
#if !MIN_VERSION_base(4,8,0)
import Data.Monoid (Monoid(mappend, mempty))
import Control.Applicative ((<*))
#endif
data a =
FailH !B.ByteString String
| PartialH (B.ByteString -> HeaderParser a)
| DoneH !Header a
deriving a -> HeaderParser b -> HeaderParser a
(a -> b) -> HeaderParser a -> HeaderParser b
(forall a b. (a -> b) -> HeaderParser a -> HeaderParser b)
-> (forall a b. a -> HeaderParser b -> HeaderParser a)
-> Functor HeaderParser
forall a b. a -> HeaderParser b -> HeaderParser a
forall a b. (a -> b) -> HeaderParser a -> HeaderParser b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> HeaderParser b -> HeaderParser a
$c<$ :: forall a b. a -> HeaderParser b -> HeaderParser a
fmap :: (a -> b) -> HeaderParser a -> HeaderParser b
$cfmap :: forall a b. (a -> b) -> HeaderParser a -> HeaderParser b
Functor
instance Show a => Show (HeaderParser a) where
showsPrec :: Int -> HeaderParser a -> ShowS
showsPrec Int
d (FailH ByteString
rest String
msg) = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) ShowS
showStr
where
showStr :: ShowS
showStr = String -> ShowS
showString String
"FailH " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ByteString -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) ByteString
rest ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
" " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
msg
showsPrec Int
_ (PartialH ByteString -> HeaderParser a
_) = String -> ShowS
showString String
"PartialH <function>"
showsPrec Int
d (DoneH Header
hdr a
x) = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) ShowS
showStr
where
showStr :: ShowS
showStr = String -> ShowS
showString String
"DoneH " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Header -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Header
hdr ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
" " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) a
x
appPrec :: Int
appPrec :: Int
appPrec = Int
10
decodeHeader :: HeaderParser B.ByteString
= DecodeOptions -> HeaderParser ByteString
decodeHeaderWith DecodeOptions
defaultDecodeOptions
decodeHeaderWith :: DecodeOptions -> HeaderParser B.ByteString
!DecodeOptions
opts = (ByteString -> HeaderParser ByteString) -> HeaderParser ByteString
forall a. (ByteString -> HeaderParser a) -> HeaderParser a
PartialH (IResult ByteString Header -> HeaderParser ByteString
go (IResult ByteString Header -> HeaderParser ByteString)
-> (ByteString -> IResult ByteString Header)
-> ByteString
-> HeaderParser ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> IResult ByteString Header
parser)
where
parser :: ByteString -> IResult ByteString Header
parser = Parser Header -> ByteString -> IResult ByteString Header
forall a. Parser a -> ByteString -> Result a
A.parse (Word8 -> Parser Header
header (Word8 -> Parser Header) -> Word8 -> Parser Header
forall a b. (a -> b) -> a -> b
$ DecodeOptions -> Word8
decDelimiter DecodeOptions
opts)
go :: IResult ByteString Header -> HeaderParser ByteString
go (A.Fail ByteString
rest [String]
_ String
msg) = ByteString -> String -> HeaderParser ByteString
forall a. ByteString -> String -> HeaderParser a
FailH ByteString
rest String
err
where err :: String
err = String
"parse error (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
go (A.Partial ByteString -> IResult ByteString Header
k) = (ByteString -> HeaderParser ByteString) -> HeaderParser ByteString
forall a. (ByteString -> HeaderParser a) -> HeaderParser a
PartialH ((ByteString -> HeaderParser ByteString)
-> HeaderParser ByteString)
-> (ByteString -> HeaderParser ByteString)
-> HeaderParser ByteString
forall a b. (a -> b) -> a -> b
$ \ ByteString
s -> IResult ByteString Header -> HeaderParser ByteString
go (ByteString -> IResult ByteString Header
k ByteString
s)
go (A.Done ByteString
rest Header
r) = Header -> ByteString -> HeaderParser ByteString
forall a. Header -> a -> HeaderParser a
DoneH Header
r ByteString
rest
data Parser a =
Fail !B.ByteString String
| Many [Either String a] (B.ByteString -> Parser a)
| Done [Either String a]
deriving a -> Parser b -> Parser a
(a -> b) -> Parser a -> Parser b
(forall a b. (a -> b) -> Parser a -> Parser b)
-> (forall a b. a -> Parser b -> Parser a) -> Functor Parser
forall a b. a -> Parser b -> Parser a
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Parser b -> Parser a
$c<$ :: forall a b. a -> Parser b -> Parser a
fmap :: (a -> b) -> Parser a -> Parser b
$cfmap :: forall a b. (a -> b) -> Parser a -> Parser b
Functor
instance Show a => Show (Parser a) where
showsPrec :: Int -> Parser a -> ShowS
showsPrec Int
d (Fail ByteString
rest String
msg) = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) ShowS
showStr
where
showStr :: ShowS
showStr = String -> ShowS
showString String
"Fail " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ByteString -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) ByteString
rest ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
" " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
msg
showsPrec Int
d (Many [Either String a]
rs ByteString -> Parser a
_) = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) ShowS
showStr
where
showStr :: ShowS
showStr = String -> ShowS
showString String
"Many " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Either String a] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [Either String a]
rs ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
" <function>"
showsPrec Int
d (Done [Either String a]
rs) = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) ShowS
showStr
where
showStr :: ShowS
showStr = String -> ShowS
showString String
"Done " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Either String a] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [Either String a]
rs
data More = Incomplete | Complete
deriving (More -> More -> Bool
(More -> More -> Bool) -> (More -> More -> Bool) -> Eq More
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: More -> More -> Bool
$c/= :: More -> More -> Bool
== :: More -> More -> Bool
$c== :: More -> More -> Bool
Eq, Int -> More -> ShowS
[More] -> ShowS
More -> String
(Int -> More -> ShowS)
-> (More -> String) -> ([More] -> ShowS) -> Show More
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [More] -> ShowS
$cshowList :: [More] -> ShowS
show :: More -> String
$cshow :: More -> String
showsPrec :: Int -> More -> ShowS
$cshowsPrec :: Int -> More -> ShowS
Show)
decode :: FromRecord a
=> HasHeader
-> Parser a
decode :: HasHeader -> Parser a
decode = DecodeOptions -> HasHeader -> Parser a
forall a. FromRecord a => DecodeOptions -> HasHeader -> Parser a
decodeWith DecodeOptions
defaultDecodeOptions
decodeWith :: FromRecord a
=> DecodeOptions
-> HasHeader
-> Parser a
decodeWith :: DecodeOptions -> HasHeader -> Parser a
decodeWith !DecodeOptions
opts HasHeader
hasHeader = (Header -> Parser a) -> DecodeOptions -> HasHeader -> Parser a
forall a.
(Header -> Parser a) -> DecodeOptions -> HasHeader -> Parser a
decodeWithP Header -> Parser a
forall a. FromRecord a => Header -> Parser a
parseRecord DecodeOptions
opts HasHeader
hasHeader
decodeWithP :: (Record -> Conversion.Parser a)
-> DecodeOptions
-> HasHeader
-> Parser a
decodeWithP :: (Header -> Parser a) -> DecodeOptions -> HasHeader -> Parser a
decodeWithP Header -> Parser a
p !DecodeOptions
opts HasHeader
hasHeader = case HasHeader
hasHeader of
HasHeader
HasHeader -> HeaderParser ByteString -> Parser a
go (DecodeOptions -> HeaderParser ByteString
decodeHeaderWith DecodeOptions
opts)
HasHeader
NoHeader -> [Either String a] -> (ByteString -> Parser a) -> Parser a
forall a. [Either String a] -> (ByteString -> Parser a) -> Parser a
Many [] ((ByteString -> Parser a) -> Parser a)
-> (ByteString -> Parser a) -> Parser a
forall a b. (a -> b) -> a -> b
$ \ ByteString
s -> (Header -> Parser a) -> DecodeOptions -> ByteString -> Parser a
forall a.
(Header -> Parser a) -> DecodeOptions -> ByteString -> Parser a
decodeWithP' Header -> Parser a
p DecodeOptions
opts ByteString
s
where go :: HeaderParser ByteString -> Parser a
go (FailH ByteString
rest String
msg) = ByteString -> String -> Parser a
forall a. ByteString -> String -> Parser a
Fail ByteString
rest String
msg
go (PartialH ByteString -> HeaderParser ByteString
k) = [Either String a] -> (ByteString -> Parser a) -> Parser a
forall a. [Either String a] -> (ByteString -> Parser a) -> Parser a
Many [] ((ByteString -> Parser a) -> Parser a)
-> (ByteString -> Parser a) -> Parser a
forall a b. (a -> b) -> a -> b
$ \ ByteString
s' -> HeaderParser ByteString -> Parser a
go (ByteString -> HeaderParser ByteString
k ByteString
s')
go (DoneH Header
_ ByteString
rest) = (Header -> Parser a) -> DecodeOptions -> ByteString -> Parser a
forall a.
(Header -> Parser a) -> DecodeOptions -> ByteString -> Parser a
decodeWithP' Header -> Parser a
p DecodeOptions
opts ByteString
rest
decodeByName :: FromNamedRecord a
=> HeaderParser (Parser a)
decodeByName :: HeaderParser (Parser a)
decodeByName = DecodeOptions -> HeaderParser (Parser a)
forall a.
FromNamedRecord a =>
DecodeOptions -> HeaderParser (Parser a)
decodeByNameWith DecodeOptions
defaultDecodeOptions
decodeByNameWith :: FromNamedRecord a
=> DecodeOptions
-> HeaderParser (Parser a)
decodeByNameWith :: DecodeOptions -> HeaderParser (Parser a)
decodeByNameWith !DecodeOptions
opts = (NamedRecord -> Parser a)
-> DecodeOptions -> HeaderParser (Parser a)
forall a.
(NamedRecord -> Parser a)
-> DecodeOptions -> HeaderParser (Parser a)
decodeByNameWithP NamedRecord -> Parser a
forall a. FromNamedRecord a => NamedRecord -> Parser a
parseNamedRecord DecodeOptions
opts
decodeByNameWithP :: (NamedRecord -> Conversion.Parser a)
-> DecodeOptions
-> HeaderParser (Parser a)
decodeByNameWithP :: (NamedRecord -> Parser a)
-> DecodeOptions -> HeaderParser (Parser a)
decodeByNameWithP NamedRecord -> Parser a
p !DecodeOptions
opts = HeaderParser ByteString -> HeaderParser (Parser a)
go (DecodeOptions -> HeaderParser ByteString
decodeHeaderWith DecodeOptions
opts)
where
go :: HeaderParser ByteString -> HeaderParser (Parser a)
go (FailH ByteString
rest String
msg) = ByteString -> String -> HeaderParser (Parser a)
forall a. ByteString -> String -> HeaderParser a
FailH ByteString
rest String
msg
go (PartialH ByteString -> HeaderParser ByteString
k) = (ByteString -> HeaderParser (Parser a)) -> HeaderParser (Parser a)
forall a. (ByteString -> HeaderParser a) -> HeaderParser a
PartialH ((ByteString -> HeaderParser (Parser a))
-> HeaderParser (Parser a))
-> (ByteString -> HeaderParser (Parser a))
-> HeaderParser (Parser a)
forall a b. (a -> b) -> a -> b
$ \ ByteString
s -> HeaderParser ByteString -> HeaderParser (Parser a)
go (ByteString -> HeaderParser ByteString
k ByteString
s)
go (DoneH Header
hdr ByteString
rest) =
Header -> Parser a -> HeaderParser (Parser a)
forall a. Header -> a -> HeaderParser a
DoneH Header
hdr ((Header -> Parser a) -> DecodeOptions -> ByteString -> Parser a
forall a.
(Header -> Parser a) -> DecodeOptions -> ByteString -> Parser a
decodeWithP' (NamedRecord -> Parser a
p (NamedRecord -> Parser a)
-> (Header -> NamedRecord) -> Header -> Parser a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header -> Header -> NamedRecord
toNamedRecord Header
hdr) DecodeOptions
opts ByteString
rest)
decodeWithP' :: (Record -> Conversion.Parser a) -> DecodeOptions -> B.ByteString
-> Parser a
decodeWithP' :: (Header -> Parser a) -> DecodeOptions -> ByteString -> Parser a
decodeWithP' Header -> Parser a
p !DecodeOptions
opts = More -> [Either String a] -> IResult ByteString Header -> Parser a
go More
Incomplete [] (IResult ByteString Header -> Parser a)
-> (ByteString -> IResult ByteString Header)
-> ByteString
-> Parser a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> IResult ByteString Header
parser
where
go :: More -> [Either String a] -> IResult ByteString Header -> Parser a
go !More
_ ![Either String a]
acc (A.Fail ByteString
rest [String]
_ String
msg)
| [Either String a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Either String a]
acc = ByteString -> String -> Parser a
forall a. ByteString -> String -> Parser a
Fail ByteString
rest String
err
| Bool
otherwise = [Either String a] -> (ByteString -> Parser a) -> Parser a
forall a. [Either String a] -> (ByteString -> Parser a) -> Parser a
Many ([Either String a] -> [Either String a]
forall a. [a] -> [a]
reverse [Either String a]
acc) (\ ByteString
s -> ByteString -> String -> Parser a
forall a. ByteString -> String -> Parser a
Fail (ByteString
rest ByteString -> ByteString -> ByteString
`B.append` ByteString
s) String
err)
where err :: String
err = String
"parse error (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
go More
Incomplete [Either String a]
acc (A.Partial ByteString -> IResult ByteString Header
k) = [Either String a] -> (ByteString -> Parser a) -> Parser a
forall a. [Either String a] -> (ByteString -> Parser a) -> Parser a
Many ([Either String a] -> [Either String a]
forall a. [a] -> [a]
reverse [Either String a]
acc) ByteString -> Parser a
cont
where cont :: ByteString -> Parser a
cont ByteString
s = More -> [Either String a] -> IResult ByteString Header -> Parser a
go More
m [] (ByteString -> IResult ByteString Header
k ByteString
s)
where m :: More
m | ByteString -> Bool
B.null ByteString
s = More
Complete
| Bool
otherwise = More
Incomplete
go More
Complete [Either String a]
_ (A.Partial ByteString -> IResult ByteString Header
_) = String -> String -> Parser a
forall a. String -> String -> a
moduleError String
"decodeWithP'" String
msg
where msg :: String
msg = String
"attoparsec should never return Partial in this case"
go More
m [Either String a]
acc (A.Done ByteString
rest Header
r)
| ByteString -> Bool
B.null ByteString
rest = case More
m of
More
Complete -> [Either String a] -> Parser a
forall a. [Either String a] -> Parser a
Done ([Either String a] -> [Either String a]
forall a. [a] -> [a]
reverse [Either String a]
acc')
More
Incomplete -> [Either String a] -> (ByteString -> Parser a) -> Parser a
forall a. [Either String a] -> (ByteString -> Parser a) -> Parser a
Many ([Either String a] -> [Either String a]
forall a. [a] -> [a]
reverse [Either String a]
acc') ([Either String a] -> ByteString -> Parser a
cont [])
| Bool
otherwise = More -> [Either String a] -> IResult ByteString Header -> Parser a
go More
m [Either String a]
acc' (ByteString -> IResult ByteString Header
parser ByteString
rest)
where cont :: [Either String a] -> ByteString -> Parser a
cont [Either String a]
acc'' ByteString
s
| ByteString -> Bool
B.null ByteString
s = [Either String a] -> Parser a
forall a. [Either String a] -> Parser a
Done ([Either String a] -> [Either String a]
forall a. [a] -> [a]
reverse [Either String a]
acc'')
| Bool
otherwise = More -> [Either String a] -> IResult ByteString Header -> Parser a
go More
Incomplete [Either String a]
acc'' (ByteString -> IResult ByteString Header
parser ByteString
s)
acc' :: [Either String a]
acc' | Header -> Bool
blankLine Header
r = [Either String a]
acc
| Bool
otherwise = let !r' :: Either String a
r' = Header -> Either String a
convert Header
r in Either String a
r' Either String a -> [Either String a] -> [Either String a]
forall a. a -> [a] -> [a]
: [Either String a]
acc
parser :: ByteString -> IResult ByteString Header
parser = Parser Header -> ByteString -> IResult ByteString Header
forall a. Parser a -> ByteString -> Result a
A.parse (Word8 -> Parser Header
record (DecodeOptions -> Word8
decDelimiter DecodeOptions
opts) Parser Header -> Parser ByteString () -> Parser Header
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Parser ByteString ()
endOfLine Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString ()
forall t. Chunk t => Parser t ()
endOfInput))
convert :: Header -> Either String a
convert = Parser a -> Either String a
forall a. Parser a -> Either String a
runParser (Parser a -> Either String a)
-> (Header -> Parser a) -> Header -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header -> Parser a
p
{-# INLINE decodeWithP' #-}
blankLine :: V.Vector B.ByteString -> Bool
blankLine :: Header -> Bool
blankLine Header
v = Header -> Int
forall a. Vector a -> Int
V.length Header
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&& (ByteString -> Bool
B.null (Header -> ByteString
forall a. Vector a -> a
V.head Header
v))
encode :: ToRecord a => Builder a -> L.ByteString
encode :: Builder a -> ByteString
encode = EncodeOptions -> Builder a -> ByteString
forall a. ToRecord a => EncodeOptions -> Builder a -> ByteString
encodeWith EncodeOptions
Encoding.defaultEncodeOptions
encodeWith :: ToRecord a => EncodeOptions -> Builder a
-> L.ByteString
encodeWith :: EncodeOptions -> Builder a -> ByteString
encodeWith EncodeOptions
opts Builder a
b =
Builder -> ByteString
Builder.toLazyByteString (Builder -> ByteString) -> Builder -> ByteString
forall a b. (a -> b) -> a -> b
$
Builder a -> Quoting -> Word8 -> Bool -> Builder
forall a. Builder a -> Quoting -> Word8 -> Bool -> Builder
runBuilder Builder a
b (EncodeOptions -> Quoting
encQuoting EncodeOptions
opts) (EncodeOptions -> Word8
encDelimiter EncodeOptions
opts) (EncodeOptions -> Bool
encUseCrLf EncodeOptions
opts)
encodeRecord :: ToRecord a => a -> Builder a
encodeRecord :: a -> Builder a
encodeRecord a
r = (Quoting -> Word8 -> Bool -> Builder) -> Builder a
forall a. (Quoting -> Word8 -> Bool -> Builder) -> Builder a
Builder ((Quoting -> Word8 -> Bool -> Builder) -> Builder a)
-> (Quoting -> Word8 -> Bool -> Builder) -> Builder a
forall a b. (a -> b) -> a -> b
$ \ Quoting
qtng Word8
delim Bool
useCrLf ->
Quoting -> Word8 -> Header -> Builder
Encoding.encodeRecord Quoting
qtng Word8
delim (a -> Header
forall a. ToRecord a => a -> Header
toRecord a
r) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> Builder
recordSep Bool
useCrLf
newtype Builder a = Builder {
Builder a -> Quoting -> Word8 -> Bool -> Builder
runBuilder :: Quoting -> Word8 -> Bool -> Builder.Builder
}
instance Semi.Semigroup (Builder a) where
Builder Quoting -> Word8 -> Bool -> Builder
f <> :: Builder a -> Builder a -> Builder a
<> Builder Quoting -> Word8 -> Bool -> Builder
g =
(Quoting -> Word8 -> Bool -> Builder) -> Builder a
forall a. (Quoting -> Word8 -> Bool -> Builder) -> Builder a
Builder ((Quoting -> Word8 -> Bool -> Builder) -> Builder a)
-> (Quoting -> Word8 -> Bool -> Builder) -> Builder a
forall a b. (a -> b) -> a -> b
$ \ Quoting
qtng Word8
delim Bool
useCrlf ->
Quoting -> Word8 -> Bool -> Builder
f Quoting
qtng Word8
delim Bool
useCrlf Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Quoting -> Word8 -> Bool -> Builder
g Quoting
qtng Word8
delim Bool
useCrlf
instance Monoid (Builder a) where
mempty :: Builder a
mempty = (Quoting -> Word8 -> Bool -> Builder) -> Builder a
forall a. (Quoting -> Word8 -> Bool -> Builder) -> Builder a
Builder (\ Quoting
_ Word8
_ Bool
_ -> Builder
forall a. Monoid a => a
mempty)
mappend :: Builder a -> Builder a -> Builder a
mappend = Builder a -> Builder a -> Builder a
forall a. Semigroup a => a -> a -> a
(Semi.<>)
encodeByName :: ToNamedRecord a => Header -> NamedBuilder a -> L.ByteString
encodeByName :: Header -> NamedBuilder a -> ByteString
encodeByName = EncodeOptions -> Header -> NamedBuilder a -> ByteString
forall a.
ToNamedRecord a =>
EncodeOptions -> Header -> NamedBuilder a -> ByteString
encodeByNameWith EncodeOptions
Encoding.defaultEncodeOptions
encodeDefaultOrderedByName :: (DefaultOrdered a, ToNamedRecord a) =>
NamedBuilder a -> L.ByteString
encodeDefaultOrderedByName :: NamedBuilder a -> ByteString
encodeDefaultOrderedByName =
EncodeOptions -> NamedBuilder a -> ByteString
forall a.
(DefaultOrdered a, ToNamedRecord a) =>
EncodeOptions -> NamedBuilder a -> ByteString
encodeDefaultOrderedByNameWith EncodeOptions
Encoding.defaultEncodeOptions
encodeByNameWith :: ToNamedRecord a => EncodeOptions -> Header -> NamedBuilder a
-> L.ByteString
encodeByNameWith :: EncodeOptions -> Header -> NamedBuilder a -> ByteString
encodeByNameWith EncodeOptions
opts Header
hdr NamedBuilder a
b =
Builder -> ByteString
Builder.toLazyByteString (Builder -> ByteString) -> Builder -> ByteString
forall a b. (a -> b) -> a -> b
$
Builder
encHdr Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
NamedBuilder a -> Header -> Quoting -> Word8 -> Bool -> Builder
forall a.
NamedBuilder a -> Header -> Quoting -> Word8 -> Bool -> Builder
runNamedBuilder NamedBuilder a
b Header
hdr (EncodeOptions -> Quoting
encQuoting EncodeOptions
opts) (EncodeOptions -> Word8
encDelimiter EncodeOptions
opts)
(EncodeOptions -> Bool
encUseCrLf EncodeOptions
opts)
where
encHdr :: Builder
encHdr
| EncodeOptions -> Bool
encIncludeHeader EncodeOptions
opts =
Quoting -> Word8 -> Header -> Builder
Encoding.encodeRecord (EncodeOptions -> Quoting
encQuoting EncodeOptions
opts) (EncodeOptions -> Word8
encDelimiter EncodeOptions
opts) Header
hdr
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> Builder
recordSep (EncodeOptions -> Bool
encUseCrLf EncodeOptions
opts)
| Bool
otherwise = Builder
forall a. Monoid a => a
mempty
encodeDefaultOrderedByNameWith ::
forall a. (DefaultOrdered a, ToNamedRecord a) =>
EncodeOptions -> NamedBuilder a -> L.ByteString
encodeDefaultOrderedByNameWith :: EncodeOptions -> NamedBuilder a -> ByteString
encodeDefaultOrderedByNameWith EncodeOptions
opts NamedBuilder a
b =
Builder -> ByteString
Builder.toLazyByteString (Builder -> ByteString) -> Builder -> ByteString
forall a b. (a -> b) -> a -> b
$
Builder
encHdr Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
NamedBuilder a -> Header -> Quoting -> Word8 -> Bool -> Builder
forall a.
NamedBuilder a -> Header -> Quoting -> Word8 -> Bool -> Builder
runNamedBuilder NamedBuilder a
b Header
hdr (EncodeOptions -> Quoting
encQuoting EncodeOptions
opts)
(EncodeOptions -> Word8
encDelimiter EncodeOptions
opts) (EncodeOptions -> Bool
encUseCrLf EncodeOptions
opts)
where
hdr :: Header
hdr = a -> Header
forall a. DefaultOrdered a => a -> Header
Conversion.headerOrder (a
forall a. HasCallStack => a
undefined :: a)
encHdr :: Builder
encHdr
| EncodeOptions -> Bool
encIncludeHeader EncodeOptions
opts =
Quoting -> Word8 -> Header -> Builder
Encoding.encodeRecord (EncodeOptions -> Quoting
encQuoting EncodeOptions
opts) (EncodeOptions -> Word8
encDelimiter EncodeOptions
opts) Header
hdr
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> Builder
recordSep (EncodeOptions -> Bool
encUseCrLf EncodeOptions
opts)
| Bool
otherwise = Builder
forall a. Monoid a => a
mempty
encodeNamedRecord :: ToNamedRecord a => a -> NamedBuilder a
encodeNamedRecord :: a -> NamedBuilder a
encodeNamedRecord a
nr = (Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a
forall a.
(Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a
NamedBuilder ((Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a)
-> (Header -> Quoting -> Word8 -> Bool -> Builder)
-> NamedBuilder a
forall a b. (a -> b) -> a -> b
$ \ Header
hdr Quoting
qtng Word8
delim Bool
useCrLf ->
Header -> Quoting -> Word8 -> NamedRecord -> Builder
Encoding.encodeNamedRecord Header
hdr Quoting
qtng Word8
delim
(a -> NamedRecord
forall a. ToNamedRecord a => a -> NamedRecord
Conversion.toNamedRecord a
nr) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> Builder
recordSep Bool
useCrLf
newtype NamedBuilder a = NamedBuilder {
NamedBuilder a -> Header -> Quoting -> Word8 -> Bool -> Builder
runNamedBuilder :: Header -> Quoting -> Word8 -> Bool -> Builder.Builder
}
instance Semigroup (NamedBuilder a) where
NamedBuilder Header -> Quoting -> Word8 -> Bool -> Builder
f <> :: NamedBuilder a -> NamedBuilder a -> NamedBuilder a
<> NamedBuilder Header -> Quoting -> Word8 -> Bool -> Builder
g =
(Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a
forall a.
(Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a
NamedBuilder ((Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a)
-> (Header -> Quoting -> Word8 -> Bool -> Builder)
-> NamedBuilder a
forall a b. (a -> b) -> a -> b
$ \ Header
hdr Quoting
qtng Word8
delim Bool
useCrlf ->
Header -> Quoting -> Word8 -> Bool -> Builder
f Header
hdr Quoting
qtng Word8
delim Bool
useCrlf Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Header -> Quoting -> Word8 -> Bool -> Builder
g Header
hdr Quoting
qtng Word8
delim Bool
useCrlf
instance Monoid (NamedBuilder a) where
mempty :: NamedBuilder a
mempty = (Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a
forall a.
(Header -> Quoting -> Word8 -> Bool -> Builder) -> NamedBuilder a
NamedBuilder (\ Header
_ Quoting
_ Word8
_ Bool
_ -> Builder
forall a. Monoid a => a
mempty)
mappend :: NamedBuilder a -> NamedBuilder a -> NamedBuilder a
mappend = NamedBuilder a -> NamedBuilder a -> NamedBuilder a
forall a. Semigroup a => a -> a -> a
(Semi.<>)
moduleError :: String -> String -> a
moduleError :: String -> String -> a
moduleError String
func String
msg = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"Data.Csv.Incremental." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
func String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg
{-# NOINLINE moduleError #-}