{-# 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
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
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
Ord, Typeable EmailAddress
EmailAddress -> DataType
EmailAddress -> Constr
(forall b. Data b => b -> b) -> EmailAddress -> 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)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(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 (m :: * -> *).
MonadPlus m =>
(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 (m :: * -> *).
Monad m =>
(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 :: forall u. Int -> (forall d. Data d => d -> u) -> EmailAddress -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> EmailAddress -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> EmailAddress -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> EmailAddress -> [u]
gmapQr :: forall r r'.
(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 :: forall r r'.
(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 (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(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 (t :: * -> *) (c :: * -> *).
Typeable t =>
(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 (c :: * -> *).
(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 (c :: * -> *).
(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
Data, Typeable, 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 = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. EmailAddress -> ByteString
toByteString
instance Read EmailAddress where
readListPrec :: ReadPrec [EmailAddress]
readListPrec = forall a. Read a => ReadPrec [a]
Read.readListPrecDefault
readPrec :: ReadPrec EmailAddress
readPrec = forall a. ReadPrec a -> ReadPrec a
Read.parens (do
ByteString
bs <- forall a. Read a => ReadPrec a
Read.readPrec
case forall a. Parser a -> ByteString -> Either String a
parseOnly (Parser ByteString EmailAddress
addrSpec forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput) ByteString
bs of
Left String
_ -> forall a. ReadPrec a
Read.pfail
Right EmailAddress
a -> 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 ByteString EmailAddress
addrSpec = do
ByteString
l <- Parser ByteString
local
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ByteString -> Int
BS.length ByteString
l forall a. Ord a => a -> a -> Bool
> Int
64) (forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"local-part of email is too long (more than 64 octets)")
Char
_ <- Char -> Parser ByteString Char
char Char
'@' forall i a. Parser i a -> String -> Parser i a
<?> String
"at sign"
ByteString
d <- Parser ByteString
domain
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ByteString -> Int
BS.length ByteString
l forall a. Num a => a -> a -> a
+ ByteString -> Int
BS.length ByteString
d forall a. Num a => a -> a -> a
+ Int
1 forall a. Ord a => a -> a -> Bool
> Int
254) (forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"email address is too long (more than 254 octets)")
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 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
'.') forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Parser ByteString
domainLabel forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`sepBy1` Char -> Parser ByteString Char
char Char
'.' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> Parser ByteString Char
char Char
'.')
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (ByteString -> Int
BS.length ByteString
parsedDomain forall a. Ord a => a -> a -> Bool
<= Int
253)
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
parsedDomain
domainLabel :: Parser ByteString
domainLabel :: Parser ByteString
domainLabel = do
ByteString
content <- forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
between1 (forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
cfws) (forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Parser a -> Parser (ByteString, a)
match (Parser ByteString Char
alphaNum forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Char -> Bool) -> Parser ()
skipWhile Char -> Bool
isAlphaNumHyphen))
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (ByteString -> Int
BS.length ByteString
content forall a. Ord a => a -> a -> Bool
<= Int
63 Bool -> Bool -> Bool
&& ByteString -> Char
BS.last ByteString
content forall a. Eq a => a -> a -> Bool
/= Char
'-')
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
content
alphaNum :: Parser Char
alphaNum :: Parser ByteString Char
alphaNum = (Char -> Bool) -> Parser ByteString 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 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
'.') forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
between1 (forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
cfws)
(Parser ByteString
atom forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString
quotedString) forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`sepBy1` Char -> Parser ByteString 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
'[' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> Char -> ByteString
BS.snoc Char
']' forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
BS.concat) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
forall (f :: * -> *) l r a.
Applicative f =>
f l -> f r -> f a -> f a
between (forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
cfws forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> Parser ByteString Char
char Char
'[') (Char -> Parser ByteString Char
char Char
']' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
cfws)
(forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
fws forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Char -> Bool) -> Parser ByteString
takeWhile1 Char -> Bool
isDomainText) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
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
'"' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> Char -> ByteString
BS.snoc Char
'"' forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
BS.concat) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
between1 (Char -> Parser ByteString Char
char Char
'"')
(forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
fws forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString
quotedContent) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
fws)
quotedContent :: Parser ByteString
quotedContent :: Parser ByteString
quotedContent = (Char -> Bool) -> Parser ByteString
takeWhile1 Char -> Bool
isQuotedText 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
'\\' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ByteString
BS.singleton) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Parser ByteString Char
char Char
'\\' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser ByteString Char
vchar forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString Char
wsp forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString Char
lf forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString Char
cr forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString Char
obsNoWsCtl forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString Char
nullChar))
cfws :: Parser ()
cfws :: Parser ()
cfws = forall (f :: * -> *) a. Alternative f => f a -> f ()
skipMany (Parser ()
comment forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ()
fws)
fws :: Parser ()
fws :: Parser ()
fws = forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser ()
wsp1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser ()
crlf forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
wsp1)) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *) a. Alternative f => f a -> f ()
skipMany1 (Parser ()
crlf forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
wsp1))
between :: Applicative f => f l -> f r -> f a -> f a
between :: forall (f :: * -> *) l r a.
Applicative f =>
f l -> f r -> f a -> f a
between f l
l f r
r f a
x = f l
l forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f a
x 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 :: forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
between1 f lr
lr f a
x = f lr
lr forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f a
x forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* f lr
lr
comment :: Parser ()
= forall (f :: * -> *) l r a.
Applicative f =>
f l -> f r -> f a -> f a
between (Char -> Parser ByteString Char
char Char
'(') (Char -> Parser ByteString Char
char Char
')') forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Alternative f => f a -> f ()
skipMany (forall (f :: * -> *) a. Functor f => f a -> f ()
void Parser ()
commentContent forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ()
fws)
commentContent :: Parser ()
= (Char -> Bool) -> Parser ()
skipWhile1 Char -> Bool
isCommentText forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void Parser ByteString
quotedPair forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ()
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 ByteString Char
nullChar = Char -> Parser ByteString Char
char Char
'\0'
skipWhile1 :: (Char -> Bool) -> Parser()
skipWhile1 :: (Char -> Bool) -> Parser ()
skipWhile1 Char -> Bool
x = (Char -> Bool) -> Parser ByteString Char
satisfy Char -> Bool
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Char -> Bool) -> Parser ()
skipWhile Char -> Bool
x
wsp1 :: Parser ()
wsp1 :: Parser ()
wsp1 = (Char -> Bool) -> Parser ()
skipWhile1 Char -> Bool
isWsp
wsp :: Parser Char
wsp :: Parser ByteString Char
wsp = (Char -> Bool) -> Parser ByteString Char
satisfy Char -> Bool
isWsp
isWsp :: Char -> Bool
isWsp :: Char -> Bool
isWsp Char
x = Char
x forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
x 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 ByteString Char
cr = Char -> Parser ByteString Char
char Char
'\r'
lf :: Parser Char
lf :: Parser ByteString Char
lf = Char -> Parser ByteString Char
char Char
'\n'
crlf :: Parser ()
crlf :: Parser ()
crlf = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ Parser ByteString Char
cr forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString Char
lf
isVchar :: Char -> Bool
isVchar :: Char -> Bool
isVchar = String -> Char -> Bool
inClass String
"\x21-\x7e"
vchar :: Parser Char
vchar :: Parser ByteString Char
vchar = (Char -> Bool) -> Parser ByteString 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 ByteString Char
obsNoWsCtl = (Char -> Bool) -> Parser ByteString Char
satisfy Char -> Bool
isObsNoWsCtl