{-# LANGUAGE ScopedTypeVariables #-}
module HsLua.Class.Util
( raiseError
, Optional (Optional, fromOptional)
, peekEither
, popValue
) where
import HsLua.Core (LuaE, NumResults, StackIndex, top)
import HsLua.Class.Peekable (Peekable (peek), PeekError)
import HsLua.Class.Pushable (Pushable (push))
import qualified Control.Monad.Catch as Catch
import qualified HsLua.Core as Lua
raiseError :: (PeekError e, Pushable a) => a -> LuaE e NumResults
raiseError :: a -> LuaE e NumResults
raiseError a
e = do
a -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push a
e
LuaE e NumResults
forall e. LuaE e NumResults
Lua.error
{-# INLINABLE raiseError #-}
newtype Optional a = Optional { Optional a -> Maybe a
fromOptional :: Maybe a }
instance Peekable a => Peekable (Optional a) where
peek :: StackIndex -> LuaE e (Optional a)
peek StackIndex
idx = do
Bool
noValue <- StackIndex -> LuaE e Bool
forall e. StackIndex -> LuaE e Bool
Lua.isnoneornil StackIndex
idx
if Bool
noValue
then Optional a -> LuaE e (Optional a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Optional a -> LuaE e (Optional a))
-> Optional a -> LuaE e (Optional a)
forall a b. (a -> b) -> a -> b
$ Maybe a -> Optional a
forall a. Maybe a -> Optional a
Optional Maybe a
forall a. Maybe a
Nothing
else Maybe a -> Optional a
forall a. Maybe a -> Optional a
Optional (Maybe a -> Optional a) -> (a -> Maybe a) -> a -> Optional a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe a
forall a. a -> Maybe a
Just (a -> Optional a) -> LuaE e a -> LuaE e (Optional a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> LuaE e a
forall a e. (Peekable a, PeekError e) => StackIndex -> LuaE e a
peek StackIndex
idx
instance Pushable a => Pushable (Optional a) where
push :: Optional a -> LuaE e ()
push (Optional Maybe a
Nothing) = LuaE e ()
forall e. LuaE e ()
Lua.pushnil
push (Optional (Just a
x)) = a -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push a
x
peekEither :: (PeekError e, Peekable a)
=> StackIndex -> LuaE e (Either e a)
peekEither :: StackIndex -> LuaE e (Either e a)
peekEither = LuaE e a -> LuaE e (Either e a)
forall e a. Exception e => LuaE e a -> LuaE e (Either e a)
Lua.try (LuaE e a -> LuaE e (Either e a))
-> (StackIndex -> LuaE e a) -> StackIndex -> LuaE e (Either e a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackIndex -> LuaE e a
forall a e. (Peekable a, PeekError e) => StackIndex -> LuaE e a
peek
popValue :: (PeekError e, Peekable a) => LuaE e a
popValue :: LuaE e a
popValue = StackIndex -> LuaE e a
forall a e. (Peekable a, PeekError e) => StackIndex -> LuaE e a
peek StackIndex
top LuaE e a -> LuaE e () -> LuaE e a
forall (m :: * -> *) a b. MonadMask m => m a -> m b -> m a
`Catch.finally` Int -> LuaE e ()
forall e. Int -> LuaE e ()
Lua.pop Int
1
{-# INLINABLE popValue #-}