{-# LANGUAGE PatternGuards #-} module Driver.Log ( Result (..) , Transition , DriverState , applyTransition , initDriverState , takeState ) where import When import Log import Driver (DriverState, initDriverState) import qualified Driver as D import Data.Time.Clock import Data.List -------------- type Transition st a b = st -> Maybe (Result a b, st) data Result a b = Result { result :: b , triggered :: [Timed a] , cancelled :: [a] } ----------------- takeState :: DriverState st a -> IO st takeState = fmap snd . D.takeState applyTransition :: (Eq a, Ord a, Show a, Show b) => LogState -> DriverState st a -> (UTCTime -> b -> IO ()) -> (a -> Transition st a b) -> a -> IO () applyTransition logState dst handleResponse transition a = D.applyTransition dst tr (tr a) where tr e st | Just (res, new_st) <- transition e st = (cancelled res, triggered res, f2 e res, new_st) | otherwise = ([], [], f1 e, st) f1 e _time = writeLog logState [{-"Event " ++ -} show e ++ {- " at " ++ show time ++ -} " was ignored."] f2 e res time = do writeLog logState $ ({-"Event " ++ -} show e {- ++ " at " ++ show time ++ " results:" -}) : map (" " ++) (showResult res) handleResponse time $ result res ------------------------ logging -------------------- showResult :: (Show a, Show b) => Result a b -> [String] showResult r = filter (not . null) [ sh " cancelled" $ map show $ cancelled r , sh " triggered" $ map f $ triggered r , sh " result " $ [show $ result r] ] where sh :: String -> [String] -> String sh _ [] = "" sh s l = s ++ ": " ++ intercalate ", " l f (w, e) = show w ++ ": " ++ show e