module Sos.Exception
  ( SosException(..)
  ) where

import Sos.Utils

import Control.Exception (Exception)
import Data.ByteString (ByteString)
import Data.Typeable (Typeable)

data SosException
  -- Error compiling the given regex.
  = SosRegexException
      ByteString -- pattern
      String     -- string reason for failure
  -- Error parsing a command template.
  | SosCommandParseException
      ByteString -- template
  -- Error applying a list of captured variables to a command template.
  | SosCommandApplyException
      [Either Int ByteString] -- template
      [ByteString]            -- captured variables
      String                  -- string reason for failure
  deriving (SosException -> SosException -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SosException -> SosException -> Bool
$c/= :: SosException -> SosException -> Bool
== :: SosException -> SosException -> Bool
$c== :: SosException -> SosException -> Bool
Eq, Typeable)

instance Show SosException where
  show :: SosException -> String
show (SosRegexException ByteString
pattrn String
err) =
    String
"Error compiling regex '" forall a. [a] -> [a] -> [a]
++ ByteString -> String
unpackBS ByteString
pattrn forall a. [a] -> [a] -> [a]
++ String
"': " forall a. [a] -> [a] -> [a]
++ String
err
  show (SosCommandParseException ByteString
template) =
    String
"Error parsing command '" forall a. [a] -> [a] -> [a]
++ ByteString -> String
unpackBS ByteString
template forall a. [a] -> [a] -> [a]
++ String
"'"
  show (SosCommandApplyException [Either Int ByteString]
template [ByteString]
vars String
err) =
    String
"Error applying template '" forall a. [a] -> [a] -> [a]
++ [Either Int ByteString] -> String
reconstruct [Either Int ByteString]
template forall a. [a] -> [a] -> [a]
++ String
"' to " forall a. [a] -> [a] -> [a]
++   forall a. Show a => a -> String
show [ByteString]
vars forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ String
err
   where
    reconstruct :: [Either Int ByteString] -> String
    reconstruct :: [Either Int ByteString] -> String
reconstruct = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
      (\case
        Left Int
n   -> Char
'\\' forall a. a -> [a] -> [a]
: forall a. Show a => a -> String
show Int
n
        Right ByteString
bs -> ByteString -> String
unpackBS ByteString
bs)

instance Exception SosException