module System.Expect.ExpectCombinators
( ExpectM (ExpectM), ExpectOption
, spawn, send, switch, wait, check
, mute, unmute
, runExpect, runExpectIO )
where
import Data.List
import Data.Maybe
import Control.Applicative
import Control.Monad
import System.Expect
data ExpectM a = ExpectM { expectMProc :: (Maybe ExpectProc -> IO (a, Maybe ExpectProc)) }
data ExpectOption a = ExpectOption { optionType :: ExpectType
, optionPattern :: String
, optionAction :: (ExpectM a) }
instance Monad ExpectM where
return a = ExpectM (\x -> return (a, x))
(ExpectM f) >>= g = ExpectM (\x -> do { (a, x') <- f x; expectMProc (g a) x'})
spawn :: String
-> ExpectM ()
spawn cmd = ExpectM (\_ -> do { p <- spawnExpect cmd; return ((), Just p) })
send :: String
-> ExpectM ()
send line = ExpectM (\x -> if isJust x then do {sendLine (fromJust x) line; return ((), x) } else return ((), x))
switch :: [ExpectOption a]
-> a
-> ExpectM a
switch options failVal = ExpectM (switch')
where switch' p@(Just proc) =
do let numOptions = zip [1..] options
cases = map (\(n,o) -> ExpectCase (optionPattern o) (optionType o) n) numOptions
result <- expectCases proc cases
if isJust result
then let opt = lookup (fromJust result) numOptions in
if isJust opt
then (expectMProc $ optionAction $ fromJust opt) p
else return (failVal, p)
else return (failVal, p)
switch' p = return (failVal, p)
wait :: ExpectType
-> String
-> ExpectM ()
wait expType pattern = ExpectM (\x -> do { expectCases (fromJust x) [ExpectCase pattern expType 1]; return ((), x) })
check :: ExpectType
-> String
-> ExpectM a
-> ExpectOption a
check expType pattern act = ExpectOption expType pattern act
unmute :: ExpectM ()
unmute = ExpectM (\x -> do { unmuteExpect; return ((),x) })
mute :: ExpectM ()
mute = ExpectM (\x -> do { muteExpect; return ((),x) })
runExpect :: ExpectM a
-> IO a
runExpect expAction = fst <$> expectMProc expAction Nothing
runExpectIO :: ExpectM (IO a)
-> IO a
runExpectIO = join . runExpect