{-# LANGUAGE LambdaCase #-}
module Sos where
import Control.Monad.Except
import Data.ByteString (ByteString)
import System.Exit
import Text.Megaparsec (ParseError)
import qualified Data.ByteString.Char8 as BS
data SosException
-- Error compiling the given regex.
= SosRegexException
ByteString -- pattern
String -- string reason for failure
-- Error parsing a command template.
| SosCommandParseException
ByteString -- template
ParseError -- failure
-- Error applying a list of captured variables to a command template.
| SosCommandApplyException
[Either Int ByteString] -- template
[ByteString] -- captured variables
String -- string reason for failure
instance Show SosException where
show (SosRegexException pattern err) = "Error compiling regex '" ++ BS.unpack pattern ++ "': " ++ err
show (SosCommandParseException template err) = "Error parsing command '" ++ BS.unpack template ++ "': " ++ show err
show (SosCommandApplyException template vars err) = "Error applying template '" ++ reconstruct template ++ "' to " ++ show vars ++ ": " ++ err
where
reconstruct :: [Either Int ByteString] -> String
reconstruct = concatMap
(\case
Left n -> '\\' : show n
Right bs -> BS.unpack bs)
type Sos a = ExceptT SosException IO a
runSos :: Sos a -> IO a
runSos act =
runExceptT act >>= \case
Left err -> do
print err
exitFailure
Right x -> pure x