{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
module Text.Email.Parser
( addrSpec
, localPart
, domainPart
, EmailAddress
, unsafeEmailAddress
, toByteString
)
where
import Control.Applicative
import Control.Monad (guard, void, when)
import Data.Attoparsec.ByteString.Char8
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BS
import Data.Data (Data, Typeable)
import GHC.Generics (Generic)
import qualified Text.Read as Read
data EmailAddress = EmailAddress ByteString ByteString
deriving (EmailAddress -> EmailAddress -> Bool
(EmailAddress -> EmailAddress -> Bool)
-> (EmailAddress -> EmailAddress -> Bool) -> Eq EmailAddress
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EmailAddress -> EmailAddress -> Bool
$c/= :: EmailAddress -> EmailAddress -> Bool
== :: EmailAddress -> EmailAddress -> Bool
$c== :: EmailAddress -> EmailAddress -> Bool
Eq, Eq EmailAddress
Eq EmailAddress
-> (EmailAddress -> EmailAddress -> Ordering)
-> (EmailAddress -> EmailAddress -> Bool)
-> (EmailAddress -> EmailAddress -> Bool)
-> (EmailAddress -> EmailAddress -> Bool)
-> (EmailAddress -> EmailAddress -> Bool)
-> (EmailAddress -> EmailAddress -> EmailAddress)
-> (EmailAddress -> EmailAddress -> EmailAddress)
-> Ord EmailAddress
EmailAddress -> EmailAddress -> Bool
EmailAddress -> EmailAddress -> Ordering
EmailAddress -> EmailAddress -> EmailAddress
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EmailAddress -> EmailAddress -> EmailAddress
$cmin :: EmailAddress -> EmailAddress -> EmailAddress
max :: EmailAddress -> EmailAddress -> EmailAddress
$cmax :: EmailAddress -> EmailAddress -> EmailAddress
>= :: EmailAddress -> EmailAddress -> Bool
$c>= :: EmailAddress -> EmailAddress -> Bool
> :: EmailAddress -> EmailAddress -> Bool
$c> :: EmailAddress -> EmailAddress -> Bool
<= :: EmailAddress -> EmailAddress -> Bool
$c<= :: EmailAddress -> EmailAddress -> Bool
< :: EmailAddress -> EmailAddress -> Bool
$c< :: EmailAddress -> EmailAddress -> Bool
compare :: EmailAddress -> EmailAddress -> Ordering
$ccompare :: EmailAddress -> EmailAddress -> Ordering
$cp1Ord :: Eq EmailAddress
Ord, Typeable EmailAddress
DataType
Constr
Typeable EmailAddress
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EmailAddress -> c EmailAddress)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c EmailAddress)
-> (EmailAddress -> Constr)
-> (EmailAddress -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c EmailAddress))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c EmailAddress))
-> ((forall b. Data b => b -> b) -> EmailAddress -> EmailAddress)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r)
-> (forall u. (forall d. Data d => d -> u) -> EmailAddress -> [u])
-> (forall u.
Int -> (forall d. Data d => d -> u) -> EmailAddress -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress)
-> Data EmailAddress
EmailAddress -> DataType
EmailAddress -> Constr
(forall b. Data b => b -> b) -> EmailAddress -> EmailAddress
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EmailAddress -> c EmailAddress
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c EmailAddress
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> EmailAddress -> u
forall u. (forall d. Data d => d -> u) -> EmailAddress -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c EmailAddress
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EmailAddress -> c EmailAddress
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c EmailAddress)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c EmailAddress)
$cEmailAddress :: Constr
$tEmailAddress :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
gmapMp :: (forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
gmapM :: (forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
gmapQi :: Int -> (forall d. Data d => d -> u) -> EmailAddress -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> EmailAddress -> u
gmapQ :: (forall d. Data d => d -> u) -> EmailAddress -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> EmailAddress -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
gmapT :: (forall b. Data b => b -> b) -> EmailAddress -> EmailAddress
$cgmapT :: (forall b. Data b => b -> b) -> EmailAddress -> EmailAddress
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c EmailAddress)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c EmailAddress)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c EmailAddress)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c EmailAddress)
dataTypeOf :: EmailAddress -> DataType
$cdataTypeOf :: EmailAddress -> DataType
toConstr :: EmailAddress -> Constr
$ctoConstr :: EmailAddress -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c EmailAddress
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c EmailAddress
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EmailAddress -> c EmailAddress
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> EmailAddress -> c EmailAddress
$cp1Data :: Typeable EmailAddress
Data, Typeable, (forall x. EmailAddress -> Rep EmailAddress x)
-> (forall x. Rep EmailAddress x -> EmailAddress)
-> Generic EmailAddress
forall x. Rep EmailAddress x -> EmailAddress
forall x. EmailAddress -> Rep EmailAddress x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep EmailAddress x -> EmailAddress
$cfrom :: forall x. EmailAddress -> Rep EmailAddress x
Generic)
unsafeEmailAddress :: ByteString -> ByteString -> EmailAddress
unsafeEmailAddress :: ByteString -> ByteString -> EmailAddress
unsafeEmailAddress = ByteString -> ByteString -> EmailAddress
EmailAddress
instance Show EmailAddress where
show :: EmailAddress -> String
show = ByteString -> String
forall a. Show a => a -> String
show (ByteString -> String)
-> (EmailAddress -> ByteString) -> EmailAddress -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EmailAddress -> ByteString
toByteString
instance Read EmailAddress where
readListPrec :: ReadPrec [EmailAddress]
readListPrec = ReadPrec [EmailAddress]
forall a. Read a => ReadPrec [a]
Read.readListPrecDefault
readPrec :: ReadPrec EmailAddress
readPrec = ReadPrec EmailAddress -> ReadPrec EmailAddress
forall a. ReadPrec a -> ReadPrec a
Read.parens (do
ByteString
bs <- ReadPrec ByteString
forall a. Read a => ReadPrec a
Read.readPrec
case Parser EmailAddress -> ByteString -> Either String EmailAddress
forall a. Parser a -> ByteString -> Either String a
parseOnly (Parser EmailAddress
addrSpec Parser EmailAddress -> Parser ByteString () -> Parser EmailAddress
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
forall t. Chunk t => Parser t ()
endOfInput) ByteString
bs of
Left String
_ -> ReadPrec EmailAddress
forall a. ReadPrec a
Read.pfail
Right EmailAddress
a -> EmailAddress -> ReadPrec EmailAddress
forall (m :: * -> *) a. Monad m => a -> m a
return EmailAddress
a)
toByteString :: EmailAddress -> ByteString
toByteString :: EmailAddress -> ByteString
toByteString (EmailAddress ByteString
l ByteString
d) = [ByteString] -> ByteString
BS.concat [ByteString
l, Char -> ByteString
BS.singleton Char
'@', ByteString
d]
localPart :: EmailAddress -> ByteString
localPart :: EmailAddress -> ByteString
localPart (EmailAddress ByteString
l ByteString
_) = ByteString
l
domainPart :: EmailAddress -> ByteString
domainPart :: EmailAddress -> ByteString
domainPart (EmailAddress ByteString
_ ByteString
d) = ByteString
d
addrSpec :: Parser EmailAddress
addrSpec :: Parser EmailAddress
addrSpec = do
ByteString
l <- Parser ByteString
local
Bool -> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ByteString -> Int
BS.length ByteString
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
64) (String -> Parser ByteString ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"local-part of email is too long (more than 64 octets)")
Char
_ <- Char -> Parser Char
char Char
'@' Parser Char -> String -> Parser Char
forall i a. Parser i a -> String -> Parser i a
<?> String
"at sign"
ByteString
d <- Parser ByteString
domain
Bool -> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ByteString -> Int
BS.length ByteString
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ByteString -> Int
BS.length ByteString
d Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
254) (String -> Parser ByteString ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"email address is too long (more than 254 octets)")
EmailAddress -> Parser EmailAddress
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> ByteString -> EmailAddress
unsafeEmailAddress ByteString
l ByteString
d)
local :: Parser ByteString
local :: Parser ByteString
local = Parser ByteString
dottedAtoms
domain :: Parser ByteString
domain :: Parser ByteString
domain = Parser ByteString
domainName Parser ByteString -> Parser ByteString -> Parser ByteString
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString
domainLiteral
domainName :: Parser ByteString
domainName :: Parser ByteString
domainName = do
ByteString
parsedDomain <- ByteString -> [ByteString] -> ByteString
BS.intercalate (Char -> ByteString
BS.singleton Char
'.') ([ByteString] -> ByteString)
-> Parser ByteString [ByteString] -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Parser ByteString
domainLabel Parser ByteString -> Parser Char -> Parser ByteString [ByteString]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`sepBy1` Char -> Parser Char
char Char
'.' Parser ByteString
-> Parser ByteString (Maybe Char) -> Parser ByteString
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Char -> Parser ByteString (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> Parser Char
char Char
'.')
Bool -> Parser ByteString ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (ByteString -> Int
BS.length ByteString
parsedDomain Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
253)
ByteString -> Parser ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
parsedDomain
domainLabel :: Parser ByteString
domainLabel :: Parser ByteString
domainLabel = do
ByteString
content <- Parser ByteString (Maybe ())
-> Parser ByteString -> Parser ByteString
forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
between1 (Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
cfws) ((ByteString, ()) -> ByteString
forall a b. (a, b) -> a
fst ((ByteString, ()) -> ByteString)
-> Parser ByteString (ByteString, ()) -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString () -> Parser ByteString (ByteString, ())
forall a. Parser a -> Parser (ByteString, a)
match (Parser Char
alphaNum Parser Char -> Parser ByteString () -> Parser ByteString ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Char -> Bool) -> Parser ByteString ()
skipWhile Char -> Bool
isAlphaNumHyphen))
Bool -> Parser ByteString ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (ByteString -> Int
BS.length ByteString
content Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
63 Bool -> Bool -> Bool
&& ByteString -> Char
BS.last ByteString
content Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'-')
ByteString -> Parser ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
content
alphaNum :: Parser Char
alphaNum :: Parser Char
alphaNum = (Char -> Bool) -> Parser Char
satisfy Char -> Bool
isAlphaNum
isAlphaNumHyphen :: Char -> Bool
isAlphaNumHyphen :: Char -> Bool
isAlphaNumHyphen Char
x = Char -> Bool
isDigit Char
x Bool -> Bool -> Bool
|| Char -> Bool
isAlpha_ascii Char
x Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-'
dottedAtoms :: Parser ByteString
dottedAtoms :: Parser ByteString
dottedAtoms = ByteString -> [ByteString] -> ByteString
BS.intercalate (Char -> ByteString
BS.singleton Char
'.') ([ByteString] -> ByteString)
-> Parser ByteString [ByteString] -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Parser ByteString (Maybe ())
-> Parser ByteString -> Parser ByteString
forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
between1 (Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
cfws)
(Parser ByteString
atom Parser ByteString -> Parser ByteString -> Parser ByteString
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString
quotedString) Parser ByteString -> Parser Char -> Parser ByteString [ByteString]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`sepBy1` Char -> Parser Char
char Char
'.'
atom :: Parser ByteString
atom :: Parser ByteString
atom = (Char -> Bool) -> Parser ByteString
takeWhile1 Char -> Bool
isAtomText
isAtomText :: Char -> Bool
isAtomText :: Char -> Bool
isAtomText Char
x = Char -> Bool
isAlphaNum Char
x Bool -> Bool -> Bool
|| String -> Char -> Bool
inClass String
"!#$%&'*+/=?^_`{|}~-" Char
x
domainLiteral :: Parser ByteString
domainLiteral :: Parser ByteString
domainLiteral =
(Char -> ByteString -> ByteString
BS.cons Char
'[' (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Char -> ByteString)
-> Char -> ByteString -> ByteString
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> Char -> ByteString
BS.snoc Char
']' (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
BS.concat) ([ByteString] -> ByteString)
-> Parser ByteString [ByteString] -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Parser Char
-> Parser Char
-> Parser ByteString [ByteString]
-> Parser ByteString [ByteString]
forall (f :: * -> *) l r a.
Applicative f =>
f l -> f r -> f a -> f a
between (Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
cfws Parser ByteString (Maybe ()) -> Parser Char -> Parser Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> Parser Char
char Char
'[') (Char -> Parser Char
char Char
']' Parser Char -> Parser ByteString (Maybe ()) -> Parser Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
cfws)
(Parser ByteString -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
fws Parser ByteString (Maybe ())
-> Parser ByteString -> Parser ByteString
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Char -> Bool) -> Parser ByteString
takeWhile1 Char -> Bool
isDomainText) Parser ByteString [ByteString]
-> Parser ByteString (Maybe ()) -> Parser ByteString [ByteString]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
fws)
isDomainText :: Char -> Bool
isDomainText :: Char -> Bool
isDomainText Char
x = String -> Char -> Bool
inClass String
"\33-\90\94-\126" Char
x Bool -> Bool -> Bool
|| Char -> Bool
isObsNoWsCtl Char
x
quotedString :: Parser ByteString
quotedString :: Parser ByteString
quotedString =
(Char -> ByteString -> ByteString
BS.cons Char
'"' (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Char -> ByteString)
-> Char -> ByteString -> ByteString
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> Char -> ByteString
BS.snoc Char
'"' (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
BS.concat) ([ByteString] -> ByteString)
-> Parser ByteString [ByteString] -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Parser Char
-> Parser ByteString [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
between1 (Char -> Parser Char
char Char
'"')
(Parser ByteString -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
fws Parser ByteString (Maybe ())
-> Parser ByteString -> Parser ByteString
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString
quotedContent) Parser ByteString [ByteString]
-> Parser ByteString (Maybe ()) -> Parser ByteString [ByteString]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ()
fws)
quotedContent :: Parser ByteString
quotedContent :: Parser ByteString
quotedContent = (Char -> Bool) -> Parser ByteString
takeWhile1 Char -> Bool
isQuotedText Parser ByteString -> Parser ByteString -> Parser ByteString
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString
quotedPair
isQuotedText :: Char -> Bool
isQuotedText :: Char -> Bool
isQuotedText Char
x = String -> Char -> Bool
inClass String
"\33\35-\91\93-\126" Char
x Bool -> Bool -> Bool
|| Char -> Bool
isObsNoWsCtl Char
x
quotedPair :: Parser ByteString
quotedPair :: Parser ByteString
quotedPair = (Char -> ByteString -> ByteString
BS.cons Char
'\\' (ByteString -> ByteString)
-> (Char -> ByteString) -> Char -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ByteString
BS.singleton) (Char -> ByteString) -> Parser Char -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Parser Char
char Char
'\\' Parser Char -> Parser Char -> Parser Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser Char
vchar Parser Char -> Parser Char -> Parser Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Char
wsp Parser Char -> Parser Char -> Parser Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Char
lf Parser Char -> Parser Char -> Parser Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Char
cr Parser Char -> Parser Char -> Parser Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Char
obsNoWsCtl Parser Char -> Parser Char -> Parser Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Char
nullChar))
cfws :: Parser ()
cfws :: Parser ByteString ()
cfws = Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f ()
skipMany (Parser ByteString ()
comment Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString ()
fws)
fws :: Parser ()
fws :: Parser ByteString ()
fws = Parser ByteString (Maybe ()) -> Parser ByteString ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser ByteString ()
wsp1 Parser ByteString ()
-> Parser ByteString (Maybe ()) -> Parser ByteString (Maybe ())
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser ByteString ()
crlf Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString ()
wsp1)) Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f ()
skipMany1 (Parser ByteString ()
crlf Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString ()
wsp1))
between :: Applicative f => f l -> f r -> f a -> f a
between :: f l -> f r -> f a -> f a
between f l
l f r
r f a
x = f l
l f l -> f a -> f a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f a
x f a -> f r -> f a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* f r
r
between1 :: Applicative f => f lr -> f a -> f a
between1 :: f lr -> f a -> f a
between1 f lr
lr f a
x = f lr
lr f lr -> f a -> f a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f a
x f a -> f lr -> f a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* f lr
lr
comment :: Parser ()
= Parser Char
-> Parser Char -> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) l r a.
Applicative f =>
f l -> f r -> f a -> f a
between (Char -> Parser Char
char Char
'(') (Char -> Parser Char
char Char
')') (Parser ByteString () -> Parser ByteString ())
-> Parser ByteString () -> Parser ByteString ()
forall a b. (a -> b) -> a -> b
$ Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f ()
skipMany (Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Parser ByteString ()
commentContent Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString ()
fws)
commentContent :: Parser ()
= (Char -> Bool) -> Parser ByteString ()
skipWhile1 Char -> Bool
isCommentText Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString -> Parser ByteString ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Parser ByteString
quotedPair Parser ByteString ()
-> Parser ByteString () -> Parser ByteString ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString ()
comment
isCommentText :: Char -> Bool
Char
x = String -> Char -> Bool
inClass String
"\33-\39\42-\91\93-\126" Char
x Bool -> Bool -> Bool
|| Char -> Bool
isObsNoWsCtl Char
x
nullChar :: Parser Char
nullChar :: Parser Char
nullChar = Char -> Parser Char
char Char
'\0'
skipWhile1 :: (Char -> Bool) -> Parser()
skipWhile1 :: (Char -> Bool) -> Parser ByteString ()
skipWhile1 Char -> Bool
x = (Char -> Bool) -> Parser Char
satisfy Char -> Bool
x Parser Char -> Parser ByteString () -> Parser ByteString ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Char -> Bool) -> Parser ByteString ()
skipWhile Char -> Bool
x
wsp1 :: Parser ()
wsp1 :: Parser ByteString ()
wsp1 = (Char -> Bool) -> Parser ByteString ()
skipWhile1 Char -> Bool
isWsp
wsp :: Parser Char
wsp :: Parser Char
wsp = (Char -> Bool) -> Parser Char
satisfy Char -> Bool
isWsp
isWsp :: Char -> Bool
isWsp :: Char -> Bool
isWsp Char
x = Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t'
isAlphaNum :: Char -> Bool
isAlphaNum :: Char -> Bool
isAlphaNum Char
x = Char -> Bool
isDigit Char
x Bool -> Bool -> Bool
|| Char -> Bool
isAlpha_ascii Char
x
cr :: Parser Char
cr :: Parser Char
cr = Char -> Parser Char
char Char
'\r'
lf :: Parser Char
lf :: Parser Char
lf = Char -> Parser Char
char Char
'\n'
crlf :: Parser ()
crlf :: Parser ByteString ()
crlf = Parser Char -> Parser ByteString ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser Char -> Parser ByteString ())
-> Parser Char -> Parser ByteString ()
forall a b. (a -> b) -> a -> b
$ Parser Char
cr Parser Char -> Parser Char -> Parser Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Char
lf
isVchar :: Char -> Bool
isVchar :: Char -> Bool
isVchar = String -> Char -> Bool
inClass String
"\x21-\x7e"
vchar :: Parser Char
vchar :: Parser Char
vchar = (Char -> Bool) -> Parser Char
satisfy Char -> Bool
isVchar
isObsNoWsCtl :: Char -> Bool
isObsNoWsCtl :: Char -> Bool
isObsNoWsCtl = String -> Char -> Bool
inClass String
"\1-\8\11-\12\14-\31\127"
obsNoWsCtl :: Parser Char
obsNoWsCtl :: Parser Char
obsNoWsCtl = (Char -> Bool) -> Parser Char
satisfy Char -> Bool
isObsNoWsCtl