ismtp-4.0.1: Network/Smtp/Types.hs
-- |
-- Module: Network.Smtp.Types
-- Copyright: (c) 2011 Ertugrul Soeylemez
-- License: BSD3
-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
--
-- Types used by ismtp.
{-# LANGUAGE
DeriveDataTypeable,
FlexibleInstances #-}
module Network.Smtp.Types
( -- * Mail monads
MailMonad(..),
Mail,
MailT,
-- * SMTP service extensions
Extension(..),
AuthMethod(..),
-- * Other types
MailConfig(..),
SmtpCommand(..),
SmtpException(..),
SmtpResponse(..)
)
where
import Control.ContStuff
import Control.Exception as Ex
import Data.ByteString (ByteString)
import Data.Enumerator
import Data.Set (Set)
import Data.Typeable
import Data.Vector (Vector)
import System.IO
import Text.Printf
-- | Mail configuration state monad. Minimal complete definition:
-- 'mapMailConfig'.
class (Functor m, Monad m) => MailMonad m where
-- | Get the current mail configuration.
getMailConfig :: m MailConfig
getMailConfig = mapMailConfig id
-- | Get supported SMTP service extensions.
getMailExtensions :: m (Set Extension)
getMailExtensions = mailExtensions <$> getMailConfig
-- | Get mail handle.
getMailHandle :: m Handle
getMailHandle = mailHandle <$> getMailConfig
-- | Get write timeout for mail session in milliseconds.
getMailWriteTimeout :: m Int
getMailWriteTimeout = mailWriteTimeout <$> getMailConfig
-- | Map over the current mail configuration with the given function
-- and return the new configuration.
mapMailConfig :: (MailConfig -> MailConfig) -> m MailConfig
-- | Modify the current mail configuration.
modifyMailConfig :: (MailConfig -> MailConfig) -> m ()
modifyMailConfig = (() <$) . mapMailConfig
-- | Set the current mail configuration.
putMailConfig :: MailConfig -> m ()
putMailConfig cfg = modifyMailConfig (const cfg)
-- | Set the set of supported SMTP service extensions.
setMailExtensions :: Set Extension -> m ()
setMailExtensions exts =
modifyMailConfig (\cfg -> cfg { mailExtensions = exts })
-- | Set the ouput handle.
setMailHandle :: Handle -> m ()
setMailHandle h = modifyMailConfig (\cfg -> cfg { mailHandle = h })
-- | Modify the mail write timeout.
setMailWriteTimeout :: Int -> m ()
setMailWriteTimeout timeout =
modifyMailConfig (\cfg -> cfg { mailWriteTimeout = timeout })
instance MailMonad (StateT r MailConfig m) where
mapMailConfig f =
StateT $ \k s0 ->
let s1 = f s0 in k s1 s1
-- | Authentication methods for the SMTP authentication extension.
data AuthMethod
= AuthMethod -- ^ We don't know any authentication methods yet.
deriving (Eq, Ord, Read, Show)
-- | SMTP service extension.
data Extension
= AuthExt (Set AuthMethod) -- ^ Authentication extension.
deriving (Eq, Ord, Read, Show)
-- | The 'MailT' monad transformer encapsulates an SMTP session.
type MailT r m = Iteratee SmtpResponse (StateT r MailConfig m)
-- | The 'Mail' monad is 'MailT' over 'IO'.
type Mail r = MailT r IO
-- | Mail session configuration.
data MailConfig =
MailConfig {
mailExtensions :: Set Extension, -- ^ Supported extensions.
mailHandle :: Handle, -- ^ Connection handle.
mailWriteTimeout :: Int -- ^ Write timeout in milliseconds.
}
-- | Failed SMTP command (used by 'SmtpException').
data SmtpCommand
= SmtpDataCmd -- ^ DATA.
| SmtpHelloCmd ByteString -- ^ EHLO or HELO with domain.
| SmtpMailFromCmd ByteString -- ^ MAIL FROM with address.
| SmtpQuitCmd -- ^ QUIT.
| SmtpRcptToCmd ByteString -- ^ RCPT TO with address.
| SmtpResetCmd -- ^ RSET.
| SmtpVerifyCmd ByteString -- ^ VRFY with the given user name.
| SmtpWelcomeCmd -- ^ Waiting for welcome message.
-- | SMTP exception.
data SmtpException
= SmtpNetworkError {
smtpErrorMessage :: String
}
| SmtpSessionError {
smtpErrorMessage :: String,
smtpErrorCommand :: SmtpCommand,
smtpErrorCode :: Integer,
smtpErrorServerMessage :: String
}
deriving Typeable
instance Ex.Exception SmtpException
instance Show SmtpException where
show (SmtpNetworkError msg) = "SMTP network error: " ++ msg
show (SmtpSessionError msg _ code srvMsg) =
printf "%s (%i): \"%s\"" msg code srvMsg
-- | SMTP response.
data SmtpResponse =
SmtpResponse {
smtpCode :: Integer, -- ^ Three digit response code.
smtpMessages :: Vector ByteString -- ^ Messages sent with the code.
}
deriving (Eq, Show)