hulk-0.1.1: src/Hulk/Types.hs
{-# OPTIONS -Wall -fno-warn-name-shadowing #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Hulk.Types where
import Control.Monad.Identity
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer
import Data.Char
import Data.Function
import Data.Map (Map)
import Data.Time
import Network
import Network.IRC hiding (Channel)
import System.IO
data Config = Config {
configListen :: PortNumber
, configHostname :: String
, configMotd :: Maybe FilePath
, configPreface :: Maybe FilePath
, configPasswd :: FilePath
, configPasswdKey :: FilePath
} deriving (Show)
newtype Ref = Ref { unRef :: Handle }
deriving (Show,Eq)
instance Ord Ref where
compare = on compare show
-- | Construct a Ref value.
newRef :: Handle -> Ref
newRef = Ref
data Error = Error String
data Env = Env {
envClients :: Map Ref Client
,envNicks :: Map Nick Ref
,envChannels :: Map ChannelName Channel
}
newtype Nick = Nick { unNick :: String } deriving Show
instance Ord Nick where
compare = on compare (map toLower . unNick)
instance Eq Nick where
(==) = on (==) (map toLower . unNick)
newtype ChannelName = ChannelName { unChanName :: String } deriving Show
instance Ord ChannelName where
compare = on compare (map toLower . unChanName)
instance Eq ChannelName where
(==) = on (==) (map toLower . unChanName)
data Channel = Channel {
channelName :: ChannelName
, channelTopic :: Maybe String
, channelUsers :: [Ref]
} deriving Show
data User = Unregistered UnregUser | Registered RegUser
deriving Show
data UnregUser = UnregUser {
unregUserName :: Maybe String
,unregUserNick :: Maybe Nick
,unregUserUser :: Maybe String
,unregUserPass :: Maybe String
} deriving Show
data RegUser = RegUser {
regUserName :: String
,regUserNick :: Nick
,regUserUser :: String
,regUserPass :: String
} deriving Show
data Client = Client {
clientRef :: Ref
, clientUser :: User
, clientHostname :: String
, clientLastPong :: UTCTime
} deriving Show
data Conn = Conn {
connRef :: Ref
,connHostname :: String
,connServerName :: String
,connTime :: UTCTime
} deriving Show
data Reply = MessageReply Ref Message | LogReply String | Close
newtype IRC m a = IRC {
runIRC :: ReaderT (UTCTime,Conn) (WriterT [Reply] (StateT Env m)) a
}
deriving (Monad
,Functor
,MonadWriter [Reply]
,MonadState Env
,MonadReader (UTCTime,Conn))
data Event = PASS | USER | NICK | PING | QUIT | TELL | JOIN | PART | PRIVMSG
| NOTICE | ISON | WHOIS | TOPIC | CONNECT | DISCONNECT | PINGPONG
| PONG
| NOTHING
deriving (Read,Show)
data RPL = RPL_WHOISUSER
| RPL_NICK
| RPL_PONG
| RPL_JOIN
| RPL_QUIT
| RPL_NOTICE
| RPL_PART
| RPL_PRIVMSG
| RPL_ISON
| RPL_JOINS
| RPL_TOPIC
| RPL_NAMEREPLY
| RPL_ENDOFNAMES
| ERR_NICKNAMEINUSE
| RPL_WELCOME
| RPL_MOTDSTART
| RPL_MOTD
| RPL_ENDOFMOTD
| RPL_WHOISIDLE
| RPL_ENDOFWHOIS
| RPL_WHOISCHANNELS
| ERR_NOSUCHNICK
| ERR_NOSUCHCHANNEL
| RPL_PING
deriving Show
fromRPL :: RPL -> String
fromRPL RPL_WHOISUSER = "311"
fromRPL RPL_NICK = "NICK"
fromRPL RPL_PONG = "PONG"
fromRPL RPL_QUIT = "QUIT"
fromRPL RPL_JOIN = "JOIN"
fromRPL RPL_NOTICE = "NOTICE"
fromRPL RPL_PART = "PART"
fromRPL RPL_PRIVMSG = "PRIVMSG"
fromRPL RPL_ISON = "303"
fromRPL RPL_JOINS = "JOIN"
fromRPL RPL_TOPIC = "TOPIC"
fromRPL RPL_NAMEREPLY = "353"
fromRPL RPL_ENDOFNAMES = "366"
fromRPL RPL_WELCOME = "001"
fromRPL RPL_MOTDSTART = "375"
fromRPL RPL_MOTD = "372"
fromRPL RPL_ENDOFMOTD = "376"
fromRPL RPL_WHOISIDLE = "317"
fromRPL RPL_WHOISCHANNELS = "319"
fromRPL RPL_ENDOFWHOIS = "318"
fromRPL ERR_NICKNAMEINUSE = "433"
fromRPL ERR_NOSUCHNICK = "401"
fromRPL ERR_NOSUCHCHANNEL = "403"
fromRPL RPL_PING = "PING"
data QuitType = RequestedQuit | SocketQuit deriving Eq
data ChannelReplyType = IncludeMe | ExcludeMe deriving Eq
class Monad m => MonadProvider m where
providePreface :: m (Maybe String)
provideMotd :: m (Maybe String)
provideKey :: m String
providePasswords :: m String
newtype HulkIO a = HulkIO { runHulkIO :: ReaderT Config IO a }
deriving (Monad,MonadReader Config,Functor,MonadIO)
newtype HulkP a = HulkP { runHulkPure :: Identity a }
deriving (Monad)
instance MonadTrans IRC where
lift m = do
s <- get
IRC $ ReaderT $ \_ -> WriterT $ StateT $ \_ -> do
a <- m
return ((a,[]),s)