{-# LANGUAGE CPP #-} module SDL.Internal.Exception ( fromC , getError , throwIf , throwIf_ , throwIf0 , throwIfNeg , throwIfNeg_ , throwIfNot0 , throwIfNot0_ , throwIfNull ) where import Control.Exception import Data.Maybe (fromMaybe) import Control.Monad import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Text (Text) import Foreign (Ptr, nullPtr) import SDL.Exception import qualified Data.ByteString as BS import qualified Data.Text.Encoding as Text import qualified SDL.Raw as Raw #if !MIN_VERSION_base(4,8,0) import Control.Applicative #endif getError :: MonadIO m => m Text getError = liftIO $ do cstr <- Raw.getError Text.decodeUtf8 <$> BS.packCString cstr {-# INLINE throwIf #-} throwIf :: MonadIO m => (a -> Bool) -> Text -> Text -> m a -> m a throwIf f caller funName m = do a <- m liftIO $ when (f a) $ (SDLCallFailed caller funName <$> getError) >>= throwIO return a {-# INLINE throwIf_ #-} throwIf_ :: MonadIO m => (a -> Bool) -> Text -> Text -> m a -> m () throwIf_ f caller funName m = throwIf f caller funName m >> return () {-# INLINE throwIfNeg #-} throwIfNeg :: (MonadIO m, Num a, Ord a) => Text -> Text -> m a -> m a throwIfNeg = throwIf (< 0) {-# INLINE throwIfNeg_ #-} throwIfNeg_ :: (MonadIO m, Num a, Ord a) => Text -> Text -> m a -> m () throwIfNeg_ = throwIf_ (< 0) {-# INLINE throwIfNull #-} throwIfNull :: (MonadIO m) => Text -> Text -> m (Ptr a) -> m (Ptr a) throwIfNull = throwIf (== nullPtr) {-# INLINE throwIf0 #-} throwIf0 :: (Eq a, MonadIO m, Num a) => Text -> Text -> m a -> m a throwIf0 = throwIf (== 0) {-# INLINE throwIfNot0 #-} throwIfNot0 :: (Eq a, MonadIO m, Num a) => Text -> Text -> m a -> m a throwIfNot0 = throwIf (/= 0) {-# INLINE throwIfNot0_ #-} throwIfNot0_ :: (Eq a, MonadIO m, Num a) => Text -> Text -> m a -> m () throwIfNot0_ = throwIf_ (/= 0) fromC :: Show a => Text -> Text -> (a -> Maybe b) -> a -> b fromC caller funName f x = fromMaybe (throw (SDLUnexpectedArgument caller funName (show x))) (f x)