attomail-0.1.0.1: src/EmailAddress.hs
{-|
Adapted from Text.EmailAddress by Dennis Gosnell (see
<https://hackage.haskell.org/package/emailaddress>)
but
without all the dependencies (like postgresql-simple ...). Uses the @email-validate@ package,
instead.
-}
{-# LANGUAGE InstanceSigs #-}
module EmailAddress
( -- * Data Type
EmailAddress(EmailAddress, unEmailAddress)
-- * Create EmailAddress
, emailAddress
, emailAddressFromText
, emailAddressFromString
-- * validation
, validate
, validateFromText
, validateFromString
-- * Unsafe creation
, unsafeEmailAddress
) where
import Text.Read (Read(readPrec), ReadPrec)
import Data.Text (Text, pack)
import Data.Text.Encoding (encodeUtf8)
import Data.ByteString hiding (pack,unpack)
import qualified Text.Email.Validate as EV
-- | wrapper around our implementation - 'EV.EmailAddress'.
newtype EmailAddress = EmailAddress
{ unEmailAddress :: EV.EmailAddress }
deriving (Eq, Ord)
-- |
-- >>> (read "\"foo@gmail.com\"") :: EmailAddress
-- "foo@gmail.com"
instance Read EmailAddress where
readPrec :: ReadPrec EmailAddress
readPrec = fmap EmailAddress readPrec
-- |
-- >>> import qualified Data.ByteString.Char8 as BS
-- >>> :set -XOverloadedStrings
-- >>> show $ unsafeEmailAddress "foo" "gmail.com"
-- "\"foo@gmail.com\""
instance Show EmailAddress where
show :: EmailAddress -> String
show = show . unEmailAddress
-- | Wrapper around 'EV.validate'.
--
-- >>> validate "foo@gmail.com"
-- Right "foo@gmail.com"
-- >>> import Data.Either (isLeft)
-- >>> isLeft $ validate "not an email address"
-- True
validate :: ByteString -> Either String EmailAddress
validate = fmap EmailAddress . EV.validate
-- | Wrapper around 'EV.emailAddress'.
--
-- Similar to 'validate', but returns 'Nothing' if the email address fails to
-- parse.
--
-- >>> emailAddress "foo@gmail.com"
-- Just "foo@gmail.com"
-- >>> emailAddress "not an email address"
-- Nothing
emailAddress :: ByteString -> Maybe EmailAddress
emailAddress = fmap EmailAddress . EV.emailAddress
-- | Create an 'EmailAddress' from a 'Text' value. See 'validate'.
validateFromText :: Text -> Either String EmailAddress
validateFromText = validate . encodeUtf8
-- | Create an 'EmailAddress' from a 'Text' value. See 'emailAddress'.
emailAddressFromText :: Text -> Maybe EmailAddress
emailAddressFromText = emailAddress . encodeUtf8
-- | Create an 'EmailAddress' from a 'String' value. See 'validate'.
validateFromString :: String -> Either String EmailAddress
validateFromString = validateFromText . pack
-- | Create an 'EmailAddress' from a 'String' value. See 'emailAddress'.
emailAddressFromString :: String -> Maybe EmailAddress
emailAddressFromString = emailAddressFromText . pack
-- | Wrapper around 'EV.unsafeEmailAddress'.
--
-- Unsafely create an 'EmailAddress' from a local part and a domain part. The
-- first argument is the local part, and the second argument is the domain
-- part.
--
-- For example, in the email address @foo\@gmail.com@, the local part is @foo@
-- and the domain part is @gmail.com@.
--
-- >>> unsafeEmailAddress "foo" "gmail.com"
-- "foo@gmail.com"
unsafeEmailAddress
:: ByteString -- ^ Local part
-> ByteString -- ^ Domain part
-> EmailAddress
unsafeEmailAddress = (EmailAddress .) . EV.unsafeEmailAddress