module Chiasma.Monad.Buffered( runTmux, ) where import Control.Monad.Free (Free(..)) import Control.Monad.IO.Class (MonadIO) import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE) import Data.Default.Class (Default(def)) import Chiasma.Api.Class (TmuxApi(..)) import Chiasma.Data.TmuxThunk (Cmd(..), Cmds(..), TmuxThunk(..), TmuxError) import Chiasma.Monad.Tmux (TmuxProg) newtype TmuxState = TmuxState [Cmd] instance Default TmuxState where def = TmuxState def interpret :: (MonadIO m, TmuxApi api) => TmuxState -> api -> TmuxProg b -> ExceptT TmuxError m b interpret (TmuxState cmds) api (Pure a) = a <$ runCommands api (const $ Right ()) (Cmds cmds) interpret (TmuxState cmds) api (Free (Read cmd decode next)) = do a <- runCommands api decode $ Cmds (cmd : cmds) interpret def api (next a) interpret (TmuxState cmds) api (Free (Write cmd next)) = interpret (TmuxState (cmd : cmds)) api (next ()) interpret _ _ (Free (Failed err)) = throwE err runTmux :: (MonadIO m, TmuxApi api) => api -> TmuxProg b -> m (Either TmuxError b) runTmux api prog = runExceptT $ interpret def api prog