    {-# LANGUAGE DeriveDataTypeable #-}
    module SDL.Raw.Error (
      -- * Error Handling
      SDLError(..),
      throwError,

      -- * Manual Error Handling
      clearError,
      getError,
      setError
    ) where

    import Control.Exception
    import Control.Monad.Catch
    import Control.Monad.IO.Class
    import Data.Typeable
    import Foreign.C.String
    import Foreign.C.Types

    -- | Note: the 'CString' is only valid until the next SDL function call. If you
    -- need to preserve the error message, make a copy of it.
    newtype SDLError = SDLError CString
      deriving (SDLError -> SDLError -> Bool
    (SDLError -> SDLError -> Bool)
    -> (SDLError -> SDLError -> Bool) -> Eq SDLError
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SDLError -> SDLError -> Bool
    == :: SDLError -> SDLError -> Bool
    $c/= :: SDLError -> SDLError -> Bool
    /= :: SDLError -> SDLError -> Bool
    Eq, Int -> SDLError -> ShowS
    [SDLError] -> ShowS
    SDLError -> String
    (Int -> SDLError -> ShowS)
    -> (SDLError -> String) -> ([SDLError] -> ShowS) -> Show SDLError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SDLError -> ShowS
    showsPrec :: Int -> SDLError -> ShowS
    $cshow :: SDLError -> String
    show :: SDLError -> String
    $cshowList :: [SDLError] -> ShowS
    showList :: [SDLError] -> ShowS
    Show, Typeable)

    instance Exception SDLError

    foreign import ccall "SDL.h SDL_ClearError" clearErrorFFI :: IO ()
    foreign import ccall "SDL.h SDL_GetError" getErrorFFI :: IO CString
    foreign import ccall "sdlhelper.c SDLHelper_SetError" setErrorFFI :: CString -> IO CInt

    throwError :: (MonadThrow m, MonadIO m) => m ()
    throwError :: forall (m :: Type -> Type). (MonadThrow m, MonadIO m) => m ()
    throwError = m CString
    forall (m :: Type -> Type). MonadIO m => m CString
    getError m CString -> (CString -> m ()) -> m ()
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
    >>= SDLError -> m ()
    forall e a. Exception e => e -> m a
    forall (m :: Type -> Type) e a.
    (MonadThrow m, Exception e) =>
    e -> m a
    throwM (SDLError -> m ()) -> (CString -> SDLError) -> CString -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CString -> SDLError
    SDLError

    clearError :: MonadIO m => m ()
    clearError :: forall (m :: Type -> Type). MonadIO m => m ()
    clearError = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
    liftIO IO ()
    clearErrorFFI
    {-# INLINE clearError #-}

    getError :: MonadIO m => m CString
    getError :: forall (m :: Type -> Type). MonadIO m => m CString
    getError = IO CString -> m CString
    forall a. IO a -> m a
    forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
    liftIO IO CString
    getErrorFFI
    {-# INLINE getError #-}

    setError :: MonadIO m => CString -> m CInt
    setError :: forall (m :: Type -> Type). MonadIO m => CString -> m CInt
    setError CString
    v1 = IO CInt -> m CInt
    forall a. IO a -> m a
    forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
    liftIO (IO CInt -> m CInt) -> IO CInt -> m CInt
    forall a b. (a -> b) -> a -> b
    $ CString -> IO CInt
    setErrorFFI CString
    v1
    {-# INLINE setError #-}