{-# Language BangPatterns #-}
module Irc.Modes
(
ModeTypes(..)
, modesLists
, modesAlwaysArg
, modesSetArg
, modesNeverArg
, modesPrefixModes
, defaultModeTypes
, defaultUmodeTypes
, splitModes
, unsplitModes
) where
import Data.Text (Text)
import qualified Data.Text as Text
import View
data ModeTypes = ModeTypes
{ _modesLists :: [Char]
, _modesAlwaysArg :: [Char]
, _modesSetArg :: [Char]
, _modesNeverArg :: [Char]
, _modesPrefixModes :: [(Char,Char)]
}
deriving Show
modesLists :: Functor f => ([Char] -> f [Char]) -> ModeTypes -> f ModeTypes
modesLists f m = (\x -> m { _modesLists = x }) <$> f (_modesLists m)
modesAlwaysArg :: Functor f => ([Char] -> f [Char]) -> ModeTypes -> f ModeTypes
modesAlwaysArg f m = (\x -> m { _modesAlwaysArg = x }) <$> f (_modesAlwaysArg m)
modesSetArg :: Functor f => ([Char] -> f [Char]) -> ModeTypes -> f ModeTypes
modesSetArg f m = (\x -> m { _modesSetArg = x }) <$> f (_modesSetArg m)
modesNeverArg :: Functor f => ([Char] -> f [Char]) -> ModeTypes -> f ModeTypes
modesNeverArg f m = (\x -> m { _modesNeverArg = x }) <$> f (_modesNeverArg m)
modesPrefixModes :: Functor f => ([(Char,Char)] -> f [(Char,Char)]) -> ModeTypes -> f ModeTypes
modesPrefixModes f m = (\x -> m { _modesPrefixModes = x }) <$> f (_modesPrefixModes m)
defaultModeTypes :: ModeTypes
defaultModeTypes = ModeTypes
{ _modesLists = "eIbq"
, _modesAlwaysArg = "k"
, _modesSetArg = "flj"
, _modesNeverArg = "CFLMPQScgimnprstz"
, _modesPrefixModes = [('o','@'),('v','+')]
}
defaultUmodeTypes :: ModeTypes
defaultUmodeTypes = ModeTypes
{ _modesLists = ""
, _modesAlwaysArg = ""
, _modesSetArg = "s"
, _modesNeverArg = "DQRZgiow"
, _modesPrefixModes = []
}
splitModes ::
ModeTypes ->
Text ->
[Text] ->
Maybe [(Bool,Char,Text)]
splitModes !icm = computeMode True . Text.unpack
where
computeMode ::
Bool ->
[Char] ->
[Text] ->
Maybe [(Bool,Char,Text)]
computeMode polarity modes args =
case modes of
[] | null args -> Just []
| otherwise -> Nothing
'+':ms -> computeMode True ms args
'-':ms -> computeMode False ms args
m:ms
| m `elem` view modesAlwaysArg icm
|| polarity && m `elem` view modesSetArg icm
|| m `elem` map fst (view modesPrefixModes icm)
|| m `elem` view modesLists icm ->
let (arg,args') =
case args of
[] -> (Text.empty,[])
x:xs -> (x,xs)
in ((polarity,m,arg):) <$> computeMode polarity ms args'
| not polarity && m `elem` view modesSetArg icm
|| m `elem` view modesNeverArg icm ->
do res <- computeMode polarity ms args
return ((polarity,m,Text.empty) : res)
| otherwise -> Nothing
unsplitModes ::
[(Bool,Char,Text)] ->
[Text]
unsplitModes modes
= Text.pack (foldr combineModeChars (const "") modes True)
: args
where
args = [arg | (_,_,arg) <- modes, not (Text.null arg)]
combineModeChars (q,m,_) rest p
| p == q = m : rest p
| q = '+' : m : rest True
| otherwise = '-' : m : rest False