    module Aws.Ses.Core
        ( SesError(..)
        , SesMetadata(..)

        , SesConfiguration(..)
        , sesEuWest1
        , sesUsEast
        , sesUsEast1
        , sesUsWest2
        , sesHttpsGet
        , sesHttpsPost

        , sesSignQuery

        , sesResponseConsumer

        , RawMessage(..)
        , Destination(..)
        , EmailAddress
        , Sender(..)
        , sesAsQuery
        ) where

    import           Aws.Core
    import qualified Blaze.ByteString.Builder       as Blaze
    import qualified Blaze.ByteString.Builder.Char8 as Blaze8
    import qualified Control.Exception              as C
    import           Control.Monad                  (mplus)
    import           Control.Monad.Trans.Resource   (throwM)
    import qualified Data.ByteString                as B
    import qualified Data.ByteString.Base64         as B64
    import           Data.ByteString.Char8          ({-IsString-})
    import           Data.IORef
    import           Data.Maybe
    import           Data.Monoid
    import qualified Data.Semigroup                 as Sem
    import           Data.Text                      (Text)
    import qualified Data.Text.Encoding             as TE
    import           Data.Typeable
    import           Prelude
    import qualified Network.HTTP.Conduit           as HTTP
    import qualified Network.HTTP.Types             as HTTP
    import           Text.XML.Cursor                (($/), ($//))
    import qualified Text.XML.Cursor                as Cu

    data SesError
        = SesError {
            SesError -> Status
    sesStatusCode   :: HTTP.Status
          , SesError -> Text
    sesErrorCode    :: Text
          , SesError -> Text
    sesErrorMessage :: Text
          }
        deriving (Int -> SesError -> ShowS
    [SesError] -> ShowS
    SesError -> String
    (Int -> SesError -> ShowS)
    -> (SesError -> String) -> ([SesError] -> ShowS) -> Show SesError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SesError -> ShowS
    showsPrec :: Int -> SesError -> ShowS
    $cshow :: SesError -> String
    show :: SesError -> String
    $cshowList :: [SesError] -> ShowS
    showList :: [SesError] -> ShowS
    Show, Typeable)

    instance C.Exception SesError

    data SesMetadata
        = SesMetadata {
            SesMetadata -> Maybe Text
    requestId :: Maybe Text
          }
        deriving (Int -> SesMetadata -> ShowS
    [SesMetadata] -> ShowS
    SesMetadata -> String
    (Int -> SesMetadata -> ShowS)
    -> (SesMetadata -> String)
    -> ([SesMetadata] -> ShowS)
    -> Show SesMetadata
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SesMetadata -> ShowS
    showsPrec :: Int -> SesMetadata -> ShowS
    $cshow :: SesMetadata -> String
    show :: SesMetadata -> String
    $cshowList :: [SesMetadata] -> ShowS
    showList :: [SesMetadata] -> ShowS
    Show, Typeable)

    instance Loggable SesMetadata where
        toLogText :: SesMetadata -> Text
    toLogText (SesMetadata Maybe Text
    rid) = Text
    "SES: request ID=" Text -> Text -> Text
    forall a. Monoid a => a -> a -> a
    `mappend` Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe Text
    "<none>" Maybe Text
    rid

    instance Sem.Semigroup SesMetadata where
        SesMetadata Maybe Text
    r1 <> :: SesMetadata -> SesMetadata -> SesMetadata
    <> SesMetadata Maybe Text
    r2 = Maybe Text -> SesMetadata
    SesMetadata (Maybe Text
    r1 Maybe Text -> Maybe Text -> Maybe Text
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` Maybe Text
    r2)

    instance Monoid SesMetadata where
        mempty :: SesMetadata
    mempty = Maybe Text -> SesMetadata
    SesMetadata Maybe Text
    forall a. Maybe a
    Nothing
        mappend :: SesMetadata -> SesMetadata -> SesMetadata
    mappend = SesMetadata -> SesMetadata -> SesMetadata
    forall a. Semigroup a => a -> a -> a
    (Sem.<>)

    data SesConfiguration qt
        = SesConfiguration {
            forall qt. SesConfiguration qt -> Method
    sesiHttpMethod :: Method
          , forall qt. SesConfiguration qt -> ByteString
    sesiHost       :: B.ByteString
          }
        deriving (Int -> SesConfiguration qt -> ShowS
    [SesConfiguration qt] -> ShowS
    SesConfiguration qt -> String
    (Int -> SesConfiguration qt -> ShowS)
    -> (SesConfiguration qt -> String)
    -> ([SesConfiguration qt] -> ShowS)
    -> Show (SesConfiguration qt)
    forall qt. Int -> SesConfiguration qt -> ShowS
    forall qt. [SesConfiguration qt] -> ShowS
    forall qt. SesConfiguration qt -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall qt. Int -> SesConfiguration qt -> ShowS
    showsPrec :: Int -> SesConfiguration qt -> ShowS
    $cshow :: forall qt. SesConfiguration qt -> String
    show :: SesConfiguration qt -> String
    $cshowList :: forall qt. [SesConfiguration qt] -> ShowS
    showList :: [SesConfiguration qt] -> ShowS
    Show)

    -- HTTP is not supported right now, always use HTTPS
    instance DefaultServiceConfiguration (SesConfiguration NormalQuery) where
        defServiceConfig :: SesConfiguration NormalQuery
    defServiceConfig = ByteString -> SesConfiguration NormalQuery
    sesHttpsPost ByteString
    sesUsEast1

    instance DefaultServiceConfiguration (SesConfiguration UriOnlyQuery) where
        defServiceConfig :: SesConfiguration UriOnlyQuery
    defServiceConfig = ByteString -> SesConfiguration UriOnlyQuery
    forall qt. ByteString -> SesConfiguration qt
    sesHttpsGet ByteString
    sesUsEast1

    sesEuWest1 :: B.ByteString
    sesEuWest1 :: ByteString
    sesEuWest1 = ByteString
    "email.eu-west-1.amazonaws.com"

    sesUsEast :: B.ByteString
    sesUsEast :: ByteString
    sesUsEast = ByteString
    sesUsEast1

    sesUsEast1 :: B.ByteString
    sesUsEast1 :: ByteString
    sesUsEast1 = ByteString
    "email.us-east-1.amazonaws.com"

    sesUsWest2 :: B.ByteString
    sesUsWest2 :: ByteString
    sesUsWest2 = ByteString
    "email.us-west-2.amazonaws.com"

    sesHttpsGet :: B.ByteString -> SesConfiguration qt
    sesHttpsGet :: forall qt. ByteString -> SesConfiguration qt
    sesHttpsGet ByteString
    endpoint = Method -> ByteString -> SesConfiguration qt
    forall qt. Method -> ByteString -> SesConfiguration qt
    SesConfiguration Method
    Get ByteString
    endpoint

    sesHttpsPost :: B.ByteString -> SesConfiguration NormalQuery
    sesHttpsPost :: ByteString -> SesConfiguration NormalQuery
    sesHttpsPost ByteString
    endpoint = Method -> ByteString -> SesConfiguration NormalQuery
    forall qt. Method -> ByteString -> SesConfiguration qt
    SesConfiguration Method
    PostQuery ByteString
    endpoint

    sesSignQuery :: [(B.ByteString, B.ByteString)] -> SesConfiguration qt -> SignatureData -> SignedQuery
    sesSignQuery :: forall qt.
    [(ByteString, ByteString)]
    -> SesConfiguration qt -> SignatureData -> SignedQuery
    sesSignQuery [(ByteString, ByteString)]
    query SesConfiguration qt
    si SignatureData
    sd
        = SignedQuery {
            sqMethod :: Method
    sqMethod        = SesConfiguration qt -> Method
    forall qt. SesConfiguration qt -> Method
    sesiHttpMethod SesConfiguration qt
    si
          , sqProtocol :: Protocol
    sqProtocol      = Protocol
    HTTPS
          , sqHost :: ByteString
    sqHost          = SesConfiguration qt -> ByteString
    forall qt. SesConfiguration qt -> ByteString
    sesiHost SesConfiguration qt
    si
          , sqPort :: Int
    sqPort          = Protocol -> Int
    defaultPort Protocol
    HTTPS
          , sqPath :: ByteString
    sqPath          = ByteString
    "/"
          , sqQuery :: Query
    sqQuery         = [(ByteString, ByteString)] -> Query
    HTTP.simpleQueryToQuery [(ByteString, ByteString)]
    query'
          , sqDate :: Maybe UTCTime
    sqDate          = UTCTime -> Maybe UTCTime
    forall a. a -> Maybe a
    Just (UTCTime -> Maybe UTCTime) -> UTCTime -> Maybe UTCTime
    forall a b. (a -> b) -> a -> b
    $ SignatureData -> UTCTime
    signatureTime SignatureData
    sd
          , sqAuthorization :: Maybe (IO ByteString)
    sqAuthorization = Maybe (IO ByteString)
    forall a. Maybe a
    Nothing
          , sqContentType :: Maybe ByteString
    sqContentType   = Maybe ByteString
    forall a. Maybe a
    Nothing
          , sqContentMd5 :: Maybe (Digest MD5)
    sqContentMd5    = Maybe (Digest MD5)
    forall a. Maybe a
    Nothing
          , sqAmzHeaders :: RequestHeaders
    sqAmzHeaders    = RequestHeaders
    amzHeaders
          , sqOtherHeaders :: RequestHeaders
    sqOtherHeaders  = []
          , sqBody :: Maybe RequestBody
    sqBody          = Maybe RequestBody
    forall a. Maybe a
    Nothing
          , sqStringToSign :: ByteString
    sqStringToSign  = ByteString
    stringToSign
          }
        where
          stringToSign :: ByteString
    stringToSign  = UTCTime -> ByteString
    fmtRfc822Time (SignatureData -> UTCTime
    signatureTime SignatureData
    sd)
          credentials :: Credentials
    credentials   = SignatureData -> Credentials
    signatureCredentials SignatureData
    sd
          accessKeyId :: ByteString
    accessKeyId   = Credentials -> ByteString
    accessKeyID Credentials
    credentials
          amzHeaders :: RequestHeaders
    amzHeaders    = [Maybe (HeaderName, ByteString)] -> RequestHeaders
    forall a. [Maybe a] -> [a]
    catMaybes
                        [ (HeaderName, ByteString) -> Maybe (HeaderName, ByteString)
    forall a. a -> Maybe a
    Just (HeaderName
    "X-Amzn-Authorization", ByteString
    authorization)
                        , (HeaderName
    "x-amz-security-token",) (ByteString -> (HeaderName, ByteString))
    -> Maybe ByteString -> Maybe (HeaderName, ByteString)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Credentials -> Maybe ByteString
    iamToken Credentials
    credentials
                        ]
          authorization :: ByteString
    authorization = [ByteString] -> ByteString
    B.concat
                        [ ByteString
    "AWS3-HTTPS AWSAccessKeyId="
                        , ByteString
    accessKeyId
                        , ByteString
    ", Algorithm=HmacSHA256, Signature="
                        , Credentials -> AuthorizationHash -> ByteString -> ByteString
    signature Credentials
    credentials AuthorizationHash
    HmacSHA256 ByteString
    stringToSign
                        ]
          query' :: [(ByteString, ByteString)]
    query' = (ByteString
    "AWSAccessKeyId", ByteString
    accessKeyId) (ByteString, ByteString)
    -> [(ByteString, ByteString)] -> [(ByteString, ByteString)]
    forall a. a -> [a] -> [a]
    : [(ByteString, ByteString)]
    query

    sesResponseConsumer :: (Cu.Cursor -> Response SesMetadata a)
                        -> IORef SesMetadata
                        -> HTTPResponseConsumer a
    sesResponseConsumer :: forall a.
    (Cursor -> Response SesMetadata a)
    -> IORef SesMetadata -> HTTPResponseConsumer a
    sesResponseConsumer Cursor -> Response SesMetadata a
    inner IORef SesMetadata
    metadataRef Response (ConduitM () ByteString (ResourceT IO) ())
    resp = (Cursor -> Response SesMetadata a)
    -> IORef SesMetadata -> HTTPResponseConsumer a
    forall m a.
    Monoid m =>
    (Cursor -> Response m a) -> IORef m -> HTTPResponseConsumer a
    xmlCursorConsumer Cursor -> Response SesMetadata a
    parse IORef SesMetadata
    metadataRef Response (ConduitM () ByteString (ResourceT IO) ())
    resp
        where
          parse :: Cursor -> Response SesMetadata a
    parse Cursor
    cursor = do
            let requestId' :: Maybe Text
    requestId' = [Text] -> Maybe Text
    forall a. [a] -> Maybe a
    listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Cursor
    cursor Cursor -> (Cursor -> [Text]) -> [Text]
    forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
    $// Text -> Cursor -> [Text]
    elContent Text
    "RequestID"
            SesMetadata -> Response SesMetadata ()
    forall m. m -> Response m ()
    tellMetadata (SesMetadata -> Response SesMetadata ())
    -> SesMetadata -> Response SesMetadata ()
    forall a b. (a -> b) -> a -> b
    $ Maybe Text -> SesMetadata
    SesMetadata Maybe Text
    requestId'
            case Cursor
    cursor Cursor -> (Cursor -> [Cursor]) -> [Cursor]
    forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
    $/ Text -> Cursor -> [Cursor]
    Cu.laxElement Text
    "Error" of
              []      -> Cursor -> Response SesMetadata a
    inner Cursor
    cursor
              (Cursor
    err:[Cursor]
    _) -> Cursor -> Response SesMetadata a
    fromError Cursor
    err

          fromError :: Cursor -> Response SesMetadata a
    fromError Cursor
    cursor = do
            errCode    <- String -> [Text] -> Response SesMetadata Text
    forall (m :: * -> *) a. MonadThrow m => String -> [a] -> m a
    force String
    "Missing Error Code"    ([Text] -> Response SesMetadata Text)
    -> [Text] -> Response SesMetadata Text
    forall a b. (a -> b) -> a -> b
    $ Cursor
    cursor Cursor -> (Cursor -> [Text]) -> [Text]
    forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
    $// Text -> Cursor -> [Text]
    elContent Text
    "Code"
            errMessage <- force "Missing Error Message" $ cursor $// elContent "Message"
            throwM $ SesError (HTTP.responseStatus resp) errCode errMessage

    class SesAsQuery a where
        -- | Write a data type as a list of query parameters.
        sesAsQuery :: a -> [(B.ByteString, B.ByteString)]

    instance SesAsQuery a => SesAsQuery (Maybe a) where
        sesAsQuery :: Maybe a -> [(ByteString, ByteString)]
    sesAsQuery = [(ByteString, ByteString)]
    -> (a -> [(ByteString, ByteString)])
    -> Maybe a
    -> [(ByteString, ByteString)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] a -> [(ByteString, ByteString)]
    forall a. SesAsQuery a => a -> [(ByteString, ByteString)]
    sesAsQuery

    -- | A raw e-mail.
    data RawMessage = RawMessage { RawMessage -> ByteString
    rawMessageData :: B.ByteString }
                    deriving (RawMessage -> RawMessage -> Bool
    (RawMessage -> RawMessage -> Bool)
    -> (RawMessage -> RawMessage -> Bool) -> Eq RawMessage
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RawMessage -> RawMessage -> Bool
    == :: RawMessage -> RawMessage -> Bool
    $c/= :: RawMessage -> RawMessage -> Bool
    /= :: RawMessage -> RawMessage -> Bool
    Eq, Eq RawMessage
    Eq RawMessage =>
    (RawMessage -> RawMessage -> Ordering)
    -> (RawMessage -> RawMessage -> Bool)
    -> (RawMessage -> RawMessage -> Bool)
    -> (RawMessage -> RawMessage -> Bool)
    -> (RawMessage -> RawMessage -> Bool)
    -> (RawMessage -> RawMessage -> RawMessage)
    -> (RawMessage -> RawMessage -> RawMessage)
    -> Ord RawMessage
    RawMessage -> RawMessage -> Bool
    RawMessage -> RawMessage -> Ordering
    RawMessage -> RawMessage -> RawMessage
    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 :: RawMessage -> RawMessage -> Ordering
    compare :: RawMessage -> RawMessage -> Ordering
    $c< :: RawMessage -> RawMessage -> Bool
    < :: RawMessage -> RawMessage -> Bool
    $c<= :: RawMessage -> RawMessage -> Bool
    <= :: RawMessage -> RawMessage -> Bool
    $c> :: RawMessage -> RawMessage -> Bool
    > :: RawMessage -> RawMessage -> Bool
    $c>= :: RawMessage -> RawMessage -> Bool
    >= :: RawMessage -> RawMessage -> Bool
    $cmax :: RawMessage -> RawMessage -> RawMessage
    max :: RawMessage -> RawMessage -> RawMessage
    $cmin :: RawMessage -> RawMessage -> RawMessage
    min :: RawMessage -> RawMessage -> RawMessage
    Ord, Int -> RawMessage -> ShowS
    [RawMessage] -> ShowS
    RawMessage -> String
    (Int -> RawMessage -> ShowS)
    -> (RawMessage -> String)
    -> ([RawMessage] -> ShowS)
    -> Show RawMessage
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RawMessage -> ShowS
    showsPrec :: Int -> RawMessage -> ShowS
    $cshow :: RawMessage -> String
    show :: RawMessage -> String
    $cshowList :: [RawMessage] -> ShowS
    showList :: [RawMessage] -> ShowS
    Show, Typeable)

    instance SesAsQuery RawMessage where
        sesAsQuery :: RawMessage -> [(ByteString, ByteString)]
    sesAsQuery = ((ByteString, ByteString)
    -> [(ByteString, ByteString)] -> [(ByteString, ByteString)]
    forall a. a -> [a] -> [a]
    :[]) ((ByteString, ByteString) -> [(ByteString, ByteString)])
    -> (RawMessage -> (ByteString, ByteString))
    -> RawMessage
    -> [(ByteString, ByteString)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (,) ByteString
    "RawMessage.Data" (ByteString -> (ByteString, ByteString))
    -> (RawMessage -> ByteString)
    -> RawMessage
    -> (ByteString, ByteString)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> ByteString
    B64.encode (ByteString -> ByteString)
    -> (RawMessage -> ByteString) -> RawMessage -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . RawMessage -> ByteString
    rawMessageData

    -- | The destinations of an e-mail.
    data Destination =
        Destination
          { Destination -> [Text]
    destinationBccAddresses :: [EmailAddress]
          , Destination -> [Text]
    destinationCcAddresses  :: [EmailAddress]
          , Destination -> [Text]
    destinationToAddresses  :: [EmailAddress]
          } deriving (Destination -> Destination -> Bool
    (Destination -> Destination -> Bool)
    -> (Destination -> Destination -> Bool) -> Eq Destination
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Destination -> Destination -> Bool
    == :: Destination -> Destination -> Bool
    $c/= :: Destination -> Destination -> Bool
    /= :: Destination -> Destination -> Bool
    Eq, Eq Destination
    Eq Destination =>
    (Destination -> Destination -> Ordering)
    -> (Destination -> Destination -> Bool)
    -> (Destination -> Destination -> Bool)
    -> (Destination -> Destination -> Bool)
    -> (Destination -> Destination -> Bool)
    -> (Destination -> Destination -> Destination)
    -> (Destination -> Destination -> Destination)
    -> Ord Destination
    Destination -> Destination -> Bool
    Destination -> Destination -> Ordering
    Destination -> Destination -> Destination
    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 :: Destination -> Destination -> Ordering
    compare :: Destination -> Destination -> Ordering
    $c< :: Destination -> Destination -> Bool
    < :: Destination -> Destination -> Bool
    $c<= :: Destination -> Destination -> Bool
    <= :: Destination -> Destination -> Bool
    $c> :: Destination -> Destination -> Bool
    > :: Destination -> Destination -> Bool
    $c>= :: Destination -> Destination -> Bool
    >= :: Destination -> Destination -> Bool
    $cmax :: Destination -> Destination -> Destination
    max :: Destination -> Destination -> Destination
    $cmin :: Destination -> Destination -> Destination
    min :: Destination -> Destination -> Destination
    Ord, Int -> Destination -> ShowS
    [Destination] -> ShowS
    Destination -> String
    (Int -> Destination -> ShowS)
    -> (Destination -> String)
    -> ([Destination] -> ShowS)
    -> Show Destination
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Destination -> ShowS
    showsPrec :: Int -> Destination -> ShowS
    $cshow :: Destination -> String
    show :: Destination -> String
    $cshowList :: [Destination] -> ShowS
    showList :: [Destination] -> ShowS
    Show, Typeable)

    instance SesAsQuery Destination where
        sesAsQuery :: Destination -> [(ByteString, ByteString)]
    sesAsQuery (Destination [Text]
    bcc [Text]
    cc [Text]
    to) = [[(ByteString, ByteString)]] -> [(ByteString, ByteString)]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [ Builder -> [Text] -> [(ByteString, ByteString)]
    go (ByteString -> Builder
    s ByteString
    "Bcc") [Text]
    bcc
                                                    , Builder -> [Text] -> [(ByteString, ByteString)]
    go (ByteString -> Builder
    s ByteString
    "Cc")  [Text]
    cc
                                                    , Builder -> [Text] -> [(ByteString, ByteString)]
    go (ByteString -> Builder
    s ByteString
    "To")  [Text]
    to ]
            where
              go :: Builder -> [Text] -> [(ByteString, ByteString)]
    go Builder
    kind = (Builder -> Text -> (ByteString, ByteString))
    -> [Builder] -> [Text] -> [(ByteString, ByteString)]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith Builder -> Text -> (ByteString, ByteString)
    f ((Int -> Builder) -> [Int] -> [Builder]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Builder
    forall a. Show a => a -> Builder
    Blaze8.fromShow [Int
    one..])
                  where txt :: Builder
    txt = Builder
    kind Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ByteString -> Builder
    s ByteString
    "Addresses.member."
                        f :: Builder -> Text -> (ByteString, ByteString)
    f Builder
    n Text
    v = ( Builder -> ByteString
    Blaze.toByteString (Builder
    txt Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder
    n)
                                , Text -> ByteString
    TE.encodeUtf8 Text
    v )
              s :: ByteString -> Builder
    s = ByteString -> Builder
    Blaze.fromByteString
              one :: Int
    one = Int
    1 :: Int

    instance Sem.Semigroup Destination where
        (Destination [Text]
    a1 [Text]
    a2 [Text]
    a3) <> :: Destination -> Destination -> Destination
    <> (Destination [Text]
    b1 [Text]
    b2 [Text]
    b3) =
            [Text] -> [Text] -> [Text] -> Destination
    Destination ([Text]
    a1 [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++ [Text]
    b1) ([Text]
    a2 [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++ [Text]
    b2) ([Text]
    a3 [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++ [Text]
    b3)

    instance Monoid Destination where
        mempty :: Destination
    mempty = [Text] -> [Text] -> [Text] -> Destination
    Destination [] [] []
        mappend :: Destination -> Destination -> Destination
    mappend = Destination -> Destination -> Destination
    forall a. Semigroup a => a -> a -> a
    (Sem.<>)

    -- | An e-mail address.
    type EmailAddress = Text

    -- | The sender's e-mail address.
    data Sender = Sender { Sender -> Text
    senderAddress :: EmailAddress }
                  deriving (Sender -> Sender -> Bool
    (Sender -> Sender -> Bool)
    -> (Sender -> Sender -> Bool) -> Eq Sender
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Sender -> Sender -> Bool
    == :: Sender -> Sender -> Bool
    $c/= :: Sender -> Sender -> Bool
    /= :: Sender -> Sender -> Bool
    Eq, Eq Sender
    Eq Sender =>
    (Sender -> Sender -> Ordering)
    -> (Sender -> Sender -> Bool)
    -> (Sender -> Sender -> Bool)
    -> (Sender -> Sender -> Bool)
    -> (Sender -> Sender -> Bool)
    -> (Sender -> Sender -> Sender)
    -> (Sender -> Sender -> Sender)
    -> Ord Sender
    Sender -> Sender -> Bool
    Sender -> Sender -> Ordering
    Sender -> Sender -> Sender
    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 :: Sender -> Sender -> Ordering
    compare :: Sender -> Sender -> Ordering
    $c< :: Sender -> Sender -> Bool
    < :: Sender -> Sender -> Bool
    $c<= :: Sender -> Sender -> Bool
    <= :: Sender -> Sender -> Bool
    $c> :: Sender -> Sender -> Bool
    > :: Sender -> Sender -> Bool
    $c>= :: Sender -> Sender -> Bool
    >= :: Sender -> Sender -> Bool
    $cmax :: Sender -> Sender -> Sender
    max :: Sender -> Sender -> Sender
    $cmin :: Sender -> Sender -> Sender
    min :: Sender -> Sender -> Sender
    Ord, Int -> Sender -> ShowS
    [Sender] -> ShowS
    Sender -> String
    (Int -> Sender -> ShowS)
    -> (Sender -> String) -> ([Sender] -> ShowS) -> Show Sender
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Sender -> ShowS
    showsPrec :: Int -> Sender -> ShowS
    $cshow :: Sender -> String
    show :: Sender -> String
    $cshowList :: [Sender] -> ShowS
    showList :: [Sender] -> ShowS
    Show, Typeable)

    instance SesAsQuery Sender where
        sesAsQuery :: Sender -> [(ByteString, ByteString)]
    sesAsQuery = ((ByteString, ByteString)
    -> [(ByteString, ByteString)] -> [(ByteString, ByteString)]
    forall a. a -> [a] -> [a]
    :[]) ((ByteString, ByteString) -> [(ByteString, ByteString)])
    -> (Sender -> (ByteString, ByteString))
    -> Sender
    -> [(ByteString, ByteString)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (,) ByteString
    "Source" (ByteString -> (ByteString, ByteString))
    -> (Sender -> ByteString) -> Sender -> (ByteString, ByteString)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> ByteString
    TE.encodeUtf8 (Text -> ByteString) -> (Sender -> Text) -> Sender -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Sender -> Text
    senderAddress