packages feed

fuyu-gpio-0.1.0.0: src/Fuyu/GPIO/Exception.hs

{-# LANGUAGE DeriveAnyClass #-}

-- |
-- Module      : Fuyu.GPIO.Exception
-- Description : Exception types for fuyu-gpio operations.
-- Maintainer  : BassGT
-- Stability   : experimental
-- Portability : POSIX
--
-- High-level exception type 'GpioException' thrown by fuyu-gpio operations.
module Fuyu.GPIO.Exception
  ( GpioException(..)
  , unwrapOrThrow
  ) where

import Control.Exception (Exception, throwIO)
import System.OsPath.Posix (PosixPath)
import Foreign.C.Error (Errno(..))

-- | High-level exceptions thrown by fuyu-gpio operations.
data GpioException
  = ChipOpenFailed PosixPath Errno
  | ChipInfoFailed Errno
  | LineInfoFailed Errno
  | LineSettingsNewFailed Errno
  | LineSettingsSetFailed Errno
  | LineConfigNewFailed Errno
  | RequestConfigNewFailed Errno
  | LineRequestFailed Errno
  | EventBufferNewFailed Errno
  | LineValueReadFailed Errno
  | LineValueWriteFailed Errno
  | LineReconfigureFailed Errno
  | WaitEdgeEventsFailed Errno
  | ReadEdgeEventsFailed Errno
  | WaitInfoEventFailed Errno
  | ReadInfoEventFailed Errno
  | RawEdgeEventCopyFailed Errno
  | LineInfoCopyFailed Errno
  | CustomGpioError String Errno
  | InvalidArgument String
  deriving (Eq, Exception)

instance Show GpioException where
  show (ChipOpenFailed path (Errno e)) = "ChipOpenFailed: Failed to open chip at " ++ show path ++ " (errno " ++ show e ++ ")"
  show (ChipInfoFailed (Errno e)) = "ChipInfoFailed (errno " ++ show e ++ ")"
  show (LineInfoFailed (Errno e)) = "LineInfoFailed (errno " ++ show e ++ ")"
  show (LineSettingsNewFailed (Errno e)) = "LineSettingsNewFailed (errno " ++ show e ++ ")"
  show (LineSettingsSetFailed (Errno e)) = "LineSettingsSetFailed (errno " ++ show e ++ ")"
  show (LineConfigNewFailed (Errno e)) = "LineConfigNewFailed (errno " ++ show e ++ ")"
  show (RequestConfigNewFailed (Errno e)) = "RequestConfigNewFailed (errno " ++ show e ++ ")"
  show (LineRequestFailed (Errno e)) = "LineRequestFailed (errno " ++ show e ++ ")"
  show (EventBufferNewFailed (Errno e)) = "EventBufferNewFailed (errno " ++ show e ++ ")"
  show (LineValueReadFailed (Errno e)) = "LineValueReadFailed (errno " ++ show e ++ ")"
  show (LineValueWriteFailed (Errno e)) = "LineValueWriteFailed (errno " ++ show e ++ ")"
  show (LineReconfigureFailed (Errno e)) = "LineReconfigureFailed (errno " ++ show e ++ ")"
  show (WaitEdgeEventsFailed (Errno e)) = "WaitEdgeEventsFailed (errno " ++ show e ++ ")"
  show (ReadEdgeEventsFailed (Errno e)) = "ReadEdgeEventsFailed (errno " ++ show e ++ ")"
  show (WaitInfoEventFailed (Errno e)) = "WaitInfoEventFailed (errno " ++ show e ++ ")"
  show (ReadInfoEventFailed (Errno e)) = "ReadInfoEventFailed (errno " ++ show e ++ ")"
  show (RawEdgeEventCopyFailed (Errno e)) = "RawEdgeEventCopyFailed (errno " ++ show e ++ ")"
  show (LineInfoCopyFailed (Errno e)) = "LineInfoCopyFailed (errno " ++ show e ++ ")"
  show (CustomGpioError msg (Errno e)) = "CustomGpioError '" ++ msg ++ "' (errno " ++ show e ++ ")"
  show (InvalidArgument msg) = "InvalidArgument: " ++ msg

-- | Helper to unwrap an 'Either Errno a' from low-level FFI calls or throw a 'GpioException'.
unwrapOrThrow :: (Errno -> GpioException) -> IO (Either Errno a) -> IO a
unwrapOrThrow mkExc action = do
  res <- action
  case res of
    Left errno -> throwIO (mkExc errno)
    Right val  -> pure val