module Coadjute.Rule(
Rule(..),
Coadjute, runCoadjute,
getUserArgs,
rule, ruleM,
rule', ruleM'
) where
import Control.Arrow (first)
import Control.Monad.State (StateT(..), modify, gets)
import Control.Monad.Trans (MonadIO, liftIO)
import qualified Data.Set as Set
import Coadjute.CoData
import Coadjute.Task (Task(..), Source, Target)
data Rule =
Rule { rName :: String
, rTasks :: [Task]
}
data RuleList = RL [Rule]
addRule :: Rule -> RuleList -> RuleList
addRule r (RL rs) = RL (r:rs)
newtype Coadjute a = Co { unCo :: StateT (RuleList, [String]) CoData a }
instance Monad Coadjute where
return = Co . return
(Co rs) >>= f = Co (rs >>= unCo.f)
instance MonadIO Coadjute where liftIO = Co . liftIO
runCoadjute :: Coadjute a -> CoData ([Rule], a)
runCoadjute (Co st) = do
ua <- asks coUserArgs
(ret, (RL l, _)) <- runStateT st (RL [], ua)
return (reverse l, ret)
getUserArgs :: Coadjute [String]
getUserArgs = Co $ gets snd
rule :: String
-> [String]
-> ([Source] -> Target -> IO ())
-> [([Source],Target)]
-> Coadjute ()
rule name args action =
Co . modify . first . addRule . Rule name .
map (\(d,t) -> Task name (Set.fromList args) [t] d (action d t))
ruleM :: String
-> [String]
-> ([Source] -> [Target] -> IO ())
-> [([Source],[Target])]
-> Coadjute ()
ruleM name args action =
Co . modify . first . addRule . Rule name .
map (\(d,t) -> Task name (Set.fromList args) t d (action d t))
rule' :: String
-> ([Source] -> Target -> IO ())
-> [([Source],Target)]
-> Coadjute ()
rule' = flip rule []
ruleM' :: String
-> ([Source] -> [Target] -> IO ())
-> [([Source],[Target])]
-> Coadjute ()
ruleM' = flip ruleM []