    {-# 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

    -- | Represents an email address.
    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
    $c== :: EmailAddress -> EmailAddress -> Bool
    == :: EmailAddress -> EmailAddress -> Bool
    $c/= :: EmailAddress -> EmailAddress -> Bool
    /= :: 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
    $ccompare :: EmailAddress -> EmailAddress -> Ordering
    compare :: EmailAddress -> EmailAddress -> Ordering
    $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
    >= :: EmailAddress -> EmailAddress -> Bool
    $cmax :: EmailAddress -> EmailAddress -> EmailAddress
    max :: EmailAddress -> EmailAddress -> EmailAddress
    $cmin :: EmailAddress -> EmailAddress -> EmailAddress
    min :: EmailAddress -> EmailAddress -> EmailAddress
    Ord, Typeable EmailAddress
    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 -> Constr
    EmailAddress -> DataType
    (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)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> EmailAddress -> c EmailAddress
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> EmailAddress -> c EmailAddress
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c EmailAddress
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c EmailAddress
    $ctoConstr :: EmailAddress -> Constr
    toConstr :: EmailAddress -> Constr
    $cdataTypeOf :: EmailAddress -> DataType
    dataTypeOf :: EmailAddress -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c EmailAddress)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c EmailAddress)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c EmailAddress)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c EmailAddress)
    $cgmapT :: (forall b. Data b => b -> b) -> EmailAddress -> EmailAddress
    gmapT :: (forall b. Data b => b -> b) -> EmailAddress -> EmailAddress
    $cgmapQl :: 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
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> EmailAddress -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> EmailAddress -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> EmailAddress -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> EmailAddress -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> EmailAddress -> u
    $cgmapM :: forall (m :: * -> *).
    Monad 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
    $cgmapMp :: 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
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> EmailAddress -> m EmailAddress
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> EmailAddress -> m 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
    $cfrom :: forall x. EmailAddress -> Rep EmailAddress x
    from :: forall x. EmailAddress -> Rep EmailAddress x
    $cto :: forall x. Rep EmailAddress x -> EmailAddress
    to :: forall x. Rep EmailAddress x -> EmailAddress
    Generic)

    -- | Creates an email address without validating it.
    --   You should only use this when reading data from
    --   somewhere it has already been validated (e.g. a
    --   database).
    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
            bs <- ReadPrec ByteString
    forall a. Read a => ReadPrec a
    Read.readPrec
            case parseOnly (addrSpec <* endOfInput) bs of
                Left  String
    _ -> ReadPrec EmailAddress
    forall a. ReadPrec a
    Read.pfail
                Right EmailAddress
    a -> EmailAddress -> ReadPrec EmailAddress
    forall a. a -> ReadPrec a
    forall (m :: * -> *) a. Monad m => a -> m a
    return EmailAddress
    a)

    -- | Converts an email address back to a ByteString
    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]

    -- | Extracts the local part of an email address.
    localPart :: EmailAddress -> ByteString
    localPart :: EmailAddress -> ByteString
    localPart (EmailAddress ByteString
    l ByteString
    _) = ByteString
    l

    -- | Extracts the domain part of an email address.
    domainPart :: EmailAddress -> ByteString
    domainPart :: EmailAddress -> ByteString
    domainPart (EmailAddress ByteString
    _ ByteString
    d) = ByteString
    d

    -- | A parser for email addresses.
    addrSpec :: Parser EmailAddress
    addrSpec :: Parser EmailAddress
    addrSpec = do
        l <- Parser ByteString
    local

        -- Maximum length of local-part is 64, per RFC3696
        when (BS.length l > 64) (fail "local-part of email is too long (more than 64 octets)")

        _ <- char '@' <?> "at sign"
        d <- domain

        -- Maximum length is 254, per Erratum 1690 on RFC3696
        when (BS.length l + BS.length d + 1 > 254) (fail "email address is too long (more than 254 octets)")

        return (unsafeEmailAddress l 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 a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser ByteString
    domainLiteral

    domainName :: Parser ByteString
    domainName :: Parser ByteString
    domainName = do
        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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString a
    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
    '.')

        -- Domain name must be no greater than 253 chars, per RFC1035
        guard (BS.length parsedDomain <= 253)
        return parsedDomain

    domainLabel :: Parser ByteString
    domainLabel :: Parser ByteString
    domainLabel = do
        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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Char -> Bool) -> Parser ByteString ()
    skipWhile Char -> Bool
    isAlphaNumHyphen))

        -- Per RFC1035:
        -- label must be no greater than 63 chars and cannot end with '-'
        -- (we already enforced that it does not start with '-')
        guard (BS.length content <= 63 && BS.last content /= '-')
        return 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 a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString a
    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 a. Parser ByteString a -> Parser ByteString [a]
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString a
    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 a. Parser ByteString a -> Parser ByteString [a]
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString a
    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 a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> (Parser Char
    vchar Parser Char -> Parser Char -> Parser Char
    forall a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser Char
    wsp Parser Char -> Parser Char -> Parser Char
    forall a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser Char
    lf Parser Char -> Parser Char -> Parser Char
    forall a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser Char
    cr Parser Char -> Parser Char -> Parser Char
    forall a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser Char
    obsNoWsCtl Parser Char -> Parser Char -> Parser Char
    forall a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    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 a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Parser ByteString ()
    wsp1)) Parser ByteString ()
    -> Parser ByteString () -> Parser ByteString ()
    forall a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    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 :: 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 f l -> f a -> f a
    forall a b. f a -> f b -> f b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> f a
    x f a -> f r -> f a
    forall a b. f a -> f b -> 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 :: forall (f :: * -> *) lr a. Applicative f => f lr -> f a -> f a
    between1 f lr
    lr f a
    x = f lr
    lr f lr -> f a -> f a
    forall a b. f a -> f b -> f b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> f a
    x f a -> f lr -> f a
    forall a b. f a -> f b -> f a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* f lr
    lr

    comment :: Parser ()
    comment :: Parser ByteString ()
    comment = 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 a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser ByteString ()
    fws)

    commentContent :: Parser ()
    commentContent :: Parser ByteString ()
    commentContent = (Char -> Bool) -> Parser ByteString ()
    skipWhile1 Char -> Bool
    isCommentText Parser ByteString ()
    -> Parser ByteString () -> Parser ByteString ()
    forall a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    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 a.
    Parser ByteString a -> Parser ByteString a -> Parser ByteString a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser ByteString ()
    comment

    isCommentText :: Char -> Bool
    isCommentText :: Char -> Bool
    isCommentText 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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    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 a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    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