module HackMail.Data.MainTypes ( module HackMail.Data.Path
, module HackMail.Data.Email
, Options (..), getOpts
, Config (..)
, Filter (..), runFilter) where
import Control.Arrow
import Control.Applicative
import Control.Monad
import Control.Monad.Reader
import Data.List
import Data.Typeable
import HackMail.Control.Misc
import HackMail.Data.Path
import HackMail.Data.Email
import HackMail.Data.ParseEmail
data SortOpt a = EqOpt a | RegOpt a
deriving Show
data Options = Opt { daemonMode :: Bool
, incomingMailLoc :: Maybe FilePath
, altFMainLoc :: Maybe FilePath
}
deriving (Eq, Show)
data Config = Conf { inboxLoc :: Path
, filterMainLoc :: FilePath
, filterMain :: Filter ()
}
deriving (Typeable)
instance Show Config where
show (Conf inbox filterMain _) = "Conf | inbox :=" ++ (show inbox)
++ " FilterMain := " ++ filterMain
getOpts = parseOpts
<<< map optNormalForm <<< pairToList
<<< (dupe map) (EqOpt, RegOpt) <<< (copy filter) (eqOpt, regOpt)
where
eqOpt = any (=='=')
regOpt = not . eqOpt
isOpt (c:_) = (c `elem` "+-")
optNormalForm :: SortOpt String -> (String, String)
optNormalForm (EqOpt s) = both tail . break (=='=') $ s
optNormalForm (RegOpt s) = both tail . break (==' ') $ s
parseOpts :: [(String, String)] -> Options
parseOpts s = Opt dMode incMailLoc altFMain
where dMode = maybeToBool . findOpt "d" $ s
incMailLoc = findOpt "i" s
altFMain = findOpt "c" s
findOpt :: String -> [(String, String)] -> Maybe String
findOpt b s = snd <$> find (\(x,y) -> x == b) s
newtype Filter a = Filter (ReaderT (Config, Email) IO a)
deriving (Monad, Functor, Typeable, MonadReader (Config, Email), MonadIO)
runFilter :: Filter a -> (Config, Email) -> IO a
runFilter (Filter f) = runReaderT f