{-# LANGUAGE LambdaCase #-}
module System.Win32.Shortcut.Error
where
import Control.Monad (join)
import Control.Monad.Except (ExceptT (..))
import Control.Monad.Trans (MonadTrans, lift)
import System.Win32.Shortcut.Internal
data HRESULTError
  = E_ABORT
  
  | E_ACCESSDENIED
  
  | E_FAIL
  
  | E_HANDLE
  
  | E_INVALIDARG
  
  | E_NOINTERFACE
  
  | E_NOTIMPL
  
  | E_OUTOFMEMORY
  
  | E_POINTER
  
  | E_UNEXPECTED
  
  | HRESULTUnknown HRESULT
  
  deriving (Show)
succeeded :: HRESULT -> Either HRESULTError ()
succeeded x
  | x == s_OK           = Right ()
  | x == e_ACCESSDENIED = Left E_ACCESSDENIED
  | x == e_FAIL         = Left E_FAIL
  | x == e_HANDLE       = Left E_HANDLE
  | x == e_INVALIDARG   = Left E_INVALIDARG
  | x == e_NOINTERFACE  = Left E_NOINTERFACE
  | x == e_NOTIMPL      = Left E_NOTIMPL
  | x == e_OUTOFMEMORY  = Left E_OUTOFMEMORY
  | x == e_POINTER      = Left E_POINTER
  | x == e_UNEXPECTED   = Left E_UNEXPECTED
  | otherwise           = Left (HRESULTUnknown x)
succeeded' :: (HRESULTError -> Either e ()) -> HRESULT -> Either e ()
succeeded' f = either f Right . succeeded
withExcept'
  :: (MonadTrans t, Monad (t m), Monad m)
  => (HRESULTError -> Either e ())
  -> t m (m HRESULT)
  -> ExceptT e (t m) ()
withExcept' f = ExceptT . fmap (succeeded' f) . join . fmap lift
overLeft :: (e1 -> e2) -> Either e1 a -> Either e2 a
overLeft f = either (Left . f) Right
data OrHRESULTError err
  = OtherError err
  
  | HRESULTError HRESULTError
  
  deriving (Show)
data CoCreateInstanceError
  = CCI_REGDB_E_CLASSNOTREG
  
  
  
  
  | CCI_CLASS_E_NOAGGREGATION
  
  | CCI_E_NOINTERFACE
  
  
  | CCI_E_POINTER
  
  | CCI_CO_E_NOTINITIALIZED
  
  deriving (Show)
toCoCreateInstanceError :: HRESULTError -> Either (OrHRESULTError CoCreateInstanceError) ()
toCoCreateInstanceError = Left . \case
  HRESULTUnknown x
    | x == -2147221164 
      -> OtherError CCI_REGDB_E_CLASSNOTREG
    | x == -2147221232 
      -> OtherError CCI_CLASS_E_NOAGGREGATION
    | x == -2147221008 
      -> OtherError CCI_CO_E_NOTINITIALIZED
  E_NOINTERFACE -> OtherError CCI_E_NOINTERFACE
  E_POINTER     -> OtherError CCI_E_POINTER
  other         -> HRESULTError other
data CoInitializeError
  = CI_RPC_E_CHANGED_MODE
  
  
  
  
  | CI_CO_E_NOTINITIALIZED
  
  
  
  deriving (Show)
toCoInitializeError :: HRESULTError -> Either (OrHRESULTError CoInitializeError) ()
toCoInitializeError = Left . \case
  HRESULTUnknown x
    | x == -2147417850 
      -> OtherError CI_RPC_E_CHANGED_MODE
    | x == -2147221008 
      -> OtherError CI_CO_E_NOTINITIALIZED
  other -> HRESULTError other
data SaveError
  = SE_S_FALSE
  
  deriving (Show)
toSaveError :: HRESULTError -> Either (OrHRESULTError SaveError) ()
toSaveError = \case
  HRESULTUnknown x
    | x == s_FALSE -> Left (OtherError SE_S_FALSE)
  other -> Left (HRESULTError other)
data LoadError
  = LE_E_OUTOFMEMORY
  
  | LE_E_FAIL
  
  
  deriving (Show)
toLoadError :: HRESULTError -> Either (OrHRESULTError LoadError) ()
toLoadError = Left . \case
  E_OUTOFMEMORY -> OtherError LE_E_OUTOFMEMORY
  E_FAIL -> OtherError LE_E_FAIL
  other -> HRESULTError other
data PathError
  = Path_S_FALSE
  
  | PathTooLong
  
  deriving (Show)
toPathError :: HRESULTError -> Either (OrHRESULTError PathError) ()
toPathError = \case
  HRESULTUnknown x
    | x == s_FALSE -> Left (OtherError Path_S_FALSE)
  other -> Left (HRESULTError other)
data ArgumentsError
  = ArgumentsTooLong
  
  deriving (Show)
data WorkingDirectoryError
  = WorkingDirectoryTooLong
  deriving (Show)
data DescriptionError
  = DescriptionTooLong
  deriving (Show)
data IconLocationError
  = IconLocationTooLong
  deriving (Show)
data ShortcutError
  = InitializationError              (OrHRESULTError CoInitializeError)
  | CreateIShellLinkInterfaceError   (OrHRESULTError CoCreateInstanceError)
  | CreateIPersistFileInterfaceError (OrHRESULTError CoCreateInstanceError)
  | LoadError                        (OrHRESULTError LoadError)
  | SaveError                        (OrHRESULTError SaveError)
  | InvalidPath                      (OrHRESULTError PathError)
  | InvalidArguments                 (OrHRESULTError ArgumentsError)
  | InvalidWorkingDirectory          (OrHRESULTError WorkingDirectoryError)
  | InvalidDescription               (OrHRESULTError DescriptionError)
  | InvalidIconLocation              (OrHRESULTError IconLocationError)
  | InvalidHotkey  HRESULTError
  | InvalidShowCmd HRESULTError
  deriving (Show)