module Foreign.Lua.Module.SystemUtils
( AnyValue (..)
, Callback (..)
, invoke
, invokeWithFilePath
, ioToLua
)
where
import Control.Exception (IOException, try)
import Foreign.Lua (Lua, NumResults(..), Peekable, Pushable, StackIndex)
import qualified Foreign.Lua as Lua
newtype Callback = Callback StackIndex
instance Peekable Callback where
peek idx = do
isFn <- Lua.isfunction idx
if isFn
then return (Callback idx)
else Lua.throwException "Function expected"
instance Pushable Callback where
push (Callback idx) = Lua.pushvalue idx
newtype AnyValue = AnyValue { fromAnyValue :: StackIndex }
instance Peekable AnyValue where
peek = return . AnyValue
instance Pushable AnyValue where
push (AnyValue idx) = Lua.pushvalue idx
invoke :: Callback -> Lua NumResults
invoke callback = do
oldTop <- Lua.gettop
Lua.push callback
Lua.call 0 Lua.multret
newTop <- Lua.gettop
return . NumResults . fromIntegral . Lua.fromStackIndex $
newTop - oldTop
invokeWithFilePath :: Callback -> FilePath -> Lua NumResults
invokeWithFilePath callback filename = do
oldTop <- Lua.gettop
Lua.push callback
Lua.push filename
Lua.call (Lua.NumArgs 1) Lua.multret
newTop <- Lua.gettop
return . NumResults . fromIntegral . Lua.fromStackIndex $
newTop - oldTop
ioToLua :: IO a -> Lua a
ioToLua action = do
result <- Lua.liftIO (try action)
case result of
Right result' -> return result'
Left err -> Lua.throwException (show (err :: IOException))