    module Text.Email.Validate
        ( isValid
        , validate
        , emailAddress
        , canonicalizeEmail

        -- Re-exports:
        , EmailAddress
        , domainPart
        , localPart
        , toByteString
        , unsafeEmailAddress
        )
    where

    import Data.Attoparsec.ByteString (endOfInput, parseOnly)
    import Data.ByteString (ByteString)

    import Text.Email.Parser
        ( EmailAddress
        , addrSpec
        , domainPart
        , localPart
        , toByteString
        , unsafeEmailAddress)

    -- | Smart constructor for an email address
    emailAddress :: ByteString -> Maybe EmailAddress
    emailAddress :: ByteString -> Maybe EmailAddress
    emailAddress = (String -> Maybe EmailAddress)
    -> (EmailAddress -> Maybe EmailAddress)
    -> Either String EmailAddress
    -> Maybe EmailAddress
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe EmailAddress -> String -> Maybe EmailAddress
    forall a b. a -> b -> a
    const Maybe EmailAddress
    forall a. Maybe a
    Nothing) EmailAddress -> Maybe EmailAddress
    forall a. a -> Maybe a
    Just (Either String EmailAddress -> Maybe EmailAddress)
    -> (ByteString -> Either String EmailAddress)
    -> ByteString
    -> Maybe EmailAddress
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Either String EmailAddress
    validate

    -- | Checks that an email is valid and returns a version of it
    --   where comments and whitespace have been removed.
    --
    -- Example (requires `OverloadedStrings` to be enabled):
    --
    -- >>> canonicalizeEmail "spaces. are. allowed@example.com"
    -- Just "spaces.are.allowed@example.com"
    canonicalizeEmail :: ByteString -> Maybe ByteString
    canonicalizeEmail :: ByteString -> Maybe ByteString
    canonicalizeEmail = (EmailAddress -> ByteString)
    -> Maybe EmailAddress -> Maybe ByteString
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap EmailAddress -> ByteString
    toByteString (Maybe EmailAddress -> Maybe ByteString)
    -> (ByteString -> Maybe EmailAddress)
    -> ByteString
    -> Maybe ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Maybe EmailAddress
    emailAddress

    -- | Validates whether a particular string is an email address
    --   according to RFC5322.
    isValid :: ByteString -> Bool
    isValid :: ByteString -> Bool
    isValid = (String -> Bool)
    -> (EmailAddress -> Bool) -> Either String EmailAddress -> Bool
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Bool -> String -> Bool
    forall a b. a -> b -> a
    const Bool
    False) (Bool -> EmailAddress -> Bool
    forall a b. a -> b -> a
    const Bool
    True) (Either String EmailAddress -> Bool)
    -> (ByteString -> Either String EmailAddress) -> ByteString -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Either String EmailAddress
    validate

    -- | If you want to find out *why* a particular string is not
    --   an email address, use this.
    --
    -- Examples (both require `OverloadedStrings` to be enabled):
    --
    -- >>> validate "example@example.com"
    -- Right "example@example.com"
    --
    -- >>> validate "not.good"
    -- Left "at sign > @: not enough input"
    validate :: ByteString -> Either String EmailAddress
    validate :: ByteString -> Either String EmailAddress
    validate = Parser EmailAddress -> ByteString -> Either String EmailAddress
    forall a. Parser a -> ByteString -> Either String a
    parseOnly (Parser EmailAddress
    addrSpec Parser EmailAddress
    -> (EmailAddress -> Parser EmailAddress) -> Parser EmailAddress
    forall a b.
    Parser ByteString a
    -> (a -> Parser ByteString b) -> Parser ByteString b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \EmailAddress
    r -> Parser ByteString ()
    forall t. Chunk t => Parser t ()
    endOfInput Parser ByteString () -> Parser EmailAddress -> Parser EmailAddress
    forall a b.
    Parser ByteString a -> Parser ByteString b -> Parser ByteString b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> EmailAddress -> Parser EmailAddress
    forall a. a -> Parser ByteString a
    forall (m :: * -> *) a. Monad m => a -> m a
    return EmailAddress
    r)