2020-09-07 22:55:13 +03:00
|
|
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
|
|
|
module Command
|
|
|
|
( Command
|
|
|
|
, runCommand
|
|
|
|
, CommandError(..)
|
|
|
|
) where
|
|
|
|
|
2020-09-10 17:33:26 +03:00
|
|
|
import Control.Monad.Except (ExceptT, MonadError, runExceptT)
|
2020-09-07 22:55:13 +03:00
|
|
|
import Control.Monad.IO.Class (MonadIO)
|
|
|
|
|
|
|
|
|
|
|
|
newtype Command a = Command { _runCommand :: ExceptT CommandError IO a }
|
|
|
|
deriving (Functor, Applicative, Monad, MonadIO, MonadError CommandError)
|
|
|
|
|
|
|
|
runCommand :: Command a -> IO ()
|
|
|
|
runCommand cmd = do
|
|
|
|
errorOrResult <- runExceptT $ _runCommand cmd
|
|
|
|
case errorOrResult of
|
|
|
|
Left cmdError -> putStrLn $ "Error: " ++ _errorMsg cmdError
|
2020-09-10 17:33:26 +03:00
|
|
|
Right _ -> return ()
|
2020-09-07 22:55:13 +03:00
|
|
|
|
|
|
|
-- TODO: What if we want to recognize errors in order to handle them?
|
|
|
|
-- Should we add _commandErrorType? Should CommandError be parametrized by it, is that even possible?
|
|
|
|
data CommandError = CommandError { _errorMsg :: !String }
|