{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module HsLua.Marshalling.Peekers
(
peekNil
, peekNoneOrNil
, peekBool
, peekIntegral
, peekRealFloat
, peekByteString
, peekLazyByteString
, peekString
, peekText
, peekStringy
, peekName
, peekRead
, peekKeyValuePairs
, peekList
, peekMap
, peekSet
, choice
, peekFieldRaw
, peekIndexRaw
, peekPair
, peekTriple
, typeChecked
, reportValueOnFailure
, typeMismatchMessage
) where
import Control.Applicative (Alternative (..))
import Control.Monad ((<$!>), (>=>), void)
import Data.ByteString (ByteString)
import Data.Map (Map)
import Data.Set (Set)
import Data.String (IsString (fromString))
import HsLua.Core as Lua
import HsLua.Marshalling.Peek
import Text.Read (readMaybe)
#if !MIN_VERSION_base(4,12,0)
import Data.Semigroup (Semigroup ((<>)))
#endif
import qualified Data.ByteString.Lazy as BL
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified HsLua.Core.Unsafe as Unsafe
import qualified HsLua.Core.Utf8 as Utf8
typeChecked :: Name
-> (StackIndex -> LuaE e Bool)
-> Peeker e a
-> Peeker e a
typeChecked :: forall e a.
Name -> (StackIndex -> LuaE e Bool) -> Peeker e a -> Peeker e a
typeChecked Name
expectedType StackIndex -> LuaE e Bool
test Peeker e a
peekfn StackIndex
idx = do
Bool
v <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ StackIndex -> LuaE e Bool
test StackIndex
idx
if Bool
v
then Peeker e a
peekfn StackIndex
idx
else forall e. Name -> StackIndex -> Peek e ByteString
typeMismatchMessage Name
expectedType StackIndex
idx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a e. ByteString -> Peek e a
failPeek
typeMismatchMessage :: Name
-> StackIndex
-> Peek e ByteString
typeMismatchMessage :: forall e. Name -> StackIndex -> Peek e ByteString
typeMismatchMessage (Name ByteString
expected) StackIndex
idx = forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ do
forall e. ByteString -> StackIndex -> LuaE e ()
pushTypeMismatchError ByteString
expected StackIndex
idx
(forall e. StackIndex -> LuaE e (Maybe ByteString)
tostring StackIndex
top forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall e. Int -> LuaE e ()
pop Int
1) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just !ByteString
msg -> forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
msg
Maybe ByteString
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"Unknown type mismatch for "
, ByteString
expected
, ByteString
" at stack index "
, String -> ByteString
Utf8.fromString forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show (StackIndex -> CInt
fromStackIndex StackIndex
idx)
]
reportValueOnFailure :: Name
-> (StackIndex -> LuaE e (Maybe a))
-> Peeker e a
reportValueOnFailure :: forall e a. Name -> (StackIndex -> LuaE e (Maybe a)) -> Peeker e a
reportValueOnFailure Name
expected StackIndex -> LuaE e (Maybe a)
peekMb StackIndex
idx = do
Maybe a
res <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ StackIndex -> LuaE e (Maybe a)
peekMb StackIndex
idx
case Maybe a
res of
Just a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! a
x
Maybe a
Nothing -> forall e. Name -> StackIndex -> Peek e ByteString
typeMismatchMessage Name
expected StackIndex
idx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a e. ByteString -> Peek e a
failPeek
peekNil :: Peeker e ()
peekNil :: forall e. Peeker e ()
peekNil = forall e a.
Name -> (StackIndex -> LuaE e Bool) -> Peeker e a -> Peeker e a
typeChecked Name
"nil" forall e. StackIndex -> LuaE e Bool
Lua.isnil forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const (forall (m :: * -> *) a. Monad m => a -> m a
return ())
{-# INLINABLE peekNil #-}
peekNoneOrNil :: Peeker e ()
peekNoneOrNil :: forall e. Peeker e ()
peekNoneOrNil = forall e a.
Name -> (StackIndex -> LuaE e Bool) -> Peeker e a -> Peeker e a
typeChecked Name
"none or nil" forall e. StackIndex -> LuaE e Bool
Lua.isnoneornil forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const (forall (m :: * -> *) a. Monad m => a -> m a
return ())
{-# INLINABLE peekNoneOrNil #-}
peekBool :: Peeker e Bool
peekBool :: forall e. Peeker e Bool
peekBool = forall e a. LuaE e a -> Peek e a
liftLua forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. StackIndex -> LuaE e Bool
toboolean
toByteString :: StackIndex -> LuaE e (Maybe ByteString)
toByteString :: forall e. StackIndex -> LuaE e (Maybe ByteString)
toByteString StackIndex
idx = do
forall e. StackIndex -> LuaE e Type
ltype StackIndex
idx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Type
TypeString -> forall e. StackIndex -> LuaE e (Maybe ByteString)
tostring StackIndex
idx
Type
_ -> forall e. Int -> LuaE e Bool
checkstack Int
1 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
False -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
Bool
True -> do
forall e. StackIndex -> LuaE e ()
pushvalue StackIndex
idx
forall e. StackIndex -> LuaE e (Maybe ByteString)
tostring StackIndex
top forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall e. Int -> LuaE e ()
pop Int
1
{-# INLINABLE toByteString #-}
peekByteString :: Peeker e ByteString
peekByteString :: forall e. Peeker e ByteString
peekByteString = forall e a. Name -> (StackIndex -> LuaE e (Maybe a)) -> Peeker e a
reportValueOnFailure Name
"string" forall e. StackIndex -> LuaE e (Maybe ByteString)
toByteString
{-# INLINABLE peekByteString #-}
peekLazyByteString :: Peeker e BL.ByteString
peekLazyByteString :: forall e. Peeker e ByteString
peekLazyByteString = (ByteString -> ByteString
BL.fromStrict forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. Peeker e ByteString
peekByteString
{-# INLINABLE peekLazyByteString #-}
peekString :: Peeker e String
peekString :: forall e. Peeker e String
peekString = forall a e. IsString a => Peeker e a
peekStringy
{-# INLINABLE peekString #-}
peekStringy :: forall a e. IsString a => Peeker e a
peekStringy :: forall a e. IsString a => Peeker e a
peekStringy = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. IsString a => String -> a
fromString forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
Utf8.toString) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. Peeker e ByteString
peekByteString
{-# INLINABLE peekStringy #-}
peekText :: Peeker e T.Text
peekText :: forall e. Peeker e Text
peekText = (ByteString -> Text
Utf8.toText forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. Peeker e ByteString
peekByteString
{-# INLINABLE peekText #-}
peekName :: Peeker e Name
peekName :: forall e. Peeker e Name
peekName = (ByteString -> Name
Name forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. Peeker e ByteString
peekByteString
{-# INLINABLE peekName #-}
peekRead :: forall a e. Read a => Peeker e a
peekRead :: forall a e. Read a => Peeker e a
peekRead = forall e. Peeker e String
peekString forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall {a} {e}. Read a => String -> Peek e a
readValue
where
readValue :: String -> Peek e a
readValue String
s = case forall a. Read a => String -> Maybe a
readMaybe String
s of
Just a
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
Maybe a
Nothing -> forall a e. ByteString -> Peek e a
failPeek forall a b. (a -> b) -> a -> b
$ ByteString
"Could not read: " forall a. Semigroup a => a -> a -> a
<> String -> ByteString
Utf8.fromString String
s
peekIntegral :: forall a e. (Integral a, Read a) => Peeker e a
peekIntegral :: forall a e. (Integral a, Read a) => Peeker e a
peekIntegral StackIndex
idx = forall e a. LuaE e a -> Peek e a
liftLua (forall e. StackIndex -> LuaE e Type
ltype StackIndex
idx) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Type
TypeNumber -> forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!>
forall e a. Name -> (StackIndex -> LuaE e (Maybe a)) -> Peeker e a
reportValueOnFailure Name
"Integral" forall e. StackIndex -> LuaE e (Maybe Integer)
tointeger StackIndex
idx
Type
TypeString -> do
Just ByteString
str <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. StackIndex -> LuaE e (Maybe ByteString)
tostring StackIndex
idx
case forall a. Read a => String -> Maybe a
readMaybe (ByteString -> String
Utf8.toString ByteString
str) of
Maybe a
Nothing -> forall e. Name -> StackIndex -> Peek e ByteString
typeMismatchMessage Name
"Integral" StackIndex
idx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a e. ByteString -> Peek e a
failPeek
Just a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return a
x
Type
_ -> forall e. Name -> StackIndex -> Peek e ByteString
typeMismatchMessage Name
"Integral" StackIndex
idx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a e. ByteString -> Peek e a
failPeek
peekRealFloat :: forall a e. (RealFloat a, Read a) => Peeker e a
peekRealFloat :: forall a e. (RealFloat a, Read a) => Peeker e a
peekRealFloat StackIndex
idx = forall e a. LuaE e a -> Peek e a
liftLua (forall e. StackIndex -> LuaE e Type
ltype StackIndex
idx) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Type
TypeString -> do
Just ByteString
str <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. StackIndex -> LuaE e (Maybe ByteString)
tostring StackIndex
idx
case forall a. Read a => String -> Maybe a
readMaybe (ByteString -> String
Utf8.toString ByteString
str) of
Maybe a
Nothing -> forall e. Name -> StackIndex -> Peek e ByteString
typeMismatchMessage Name
"RealFloat" StackIndex
idx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a e. ByteString -> Peek e a
failPeek
Just a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return a
x
Type
_ -> forall a b. (Real a, Fractional b) => a -> b
realToFrac forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> forall e a. Name -> (StackIndex -> LuaE e (Maybe a)) -> Peeker e a
reportValueOnFailure Name
"RealFloat" forall e. StackIndex -> LuaE e (Maybe Number)
tonumber StackIndex
idx
peekList :: forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList :: forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e a
peekElement = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"list") forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall e a.
Name -> (StackIndex -> LuaE e Bool) -> Peeker e a -> Peeker e a
typeChecked Name
"table" forall e. StackIndex -> LuaE e Bool
istable forall a b. (a -> b) -> a -> b
$ \StackIndex
idx -> do
forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. LuaError e => Int -> String -> LuaE e ()
checkstack' Int
1 String
"retrieving a list"
let elementsAt :: [Integer] -> Peek e [a]
elementsAt [] = forall (m :: * -> *) a. Monad m => a -> m a
return []
elementsAt (Integer
i : [Integer]
is) = do
a
x <- forall e a. Name -> Peek e a -> Peek e a
retrieving (Name
"index " forall a. Semigroup a => a -> a -> a
<> forall {a}. IsString a => Integer -> a
showInt Integer
i) forall a b. (a -> b) -> a -> b
$
forall e a. LuaE e a -> Peek e a
liftLua (forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
rawgeti StackIndex
idx Integer
i) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker e a
peekElement StackIndex
top forall e a b. Peek e a -> LuaE e b -> Peek e a
`lastly` forall e. Int -> LuaE e ()
pop Int
1
[a]
xs <- [Integer] -> Peek e [a]
elementsAt [Integer]
is
forall (m :: * -> *) a. Monad m => a -> m a
return (a
xforall a. a -> [a] -> [a]
:[a]
xs)
showInt :: Integer -> a
showInt (Lua.Integer Int64
x) = forall a. IsString a => String -> a
fromString forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Int64
x
Int
listLength <- forall e a. LuaE e a -> Peek e a
liftLua (forall e. StackIndex -> LuaE e Int
rawlen StackIndex
idx)
[Integer] -> Peek e [a]
elementsAt [Integer
1..forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
listLength]
peekMap :: (LuaError e, Ord a)
=> Peeker e a -> Peeker e b -> Peeker e (Map a b)
peekMap :: forall e a b.
(LuaError e, Ord a) =>
Peeker e a -> Peeker e b -> Peeker e (Map a b)
peekMap Peeker e a
keyPeeker Peeker e b
valuePeeker = forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"Map"
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a b.
LuaError e =>
Peeker e a -> Peeker e b -> Peeker e [(a, b)]
peekKeyValuePairs Peeker e a
keyPeeker Peeker e b
valuePeeker
peekKeyValuePairs :: LuaError e
=> Peeker e a -> Peeker e b -> Peeker e [(a, b)]
peekKeyValuePairs :: forall e a b.
LuaError e =>
Peeker e a -> Peeker e b -> Peeker e [(a, b)]
peekKeyValuePairs Peeker e a
keyPeeker Peeker e b
valuePeeker =
forall e a.
Name -> (StackIndex -> LuaE e Bool) -> Peeker e a -> Peeker e a
typeChecked Name
"table" forall e. StackIndex -> LuaE e Bool
istable forall a b. (a -> b) -> a -> b
$ \StackIndex
idx -> forall e a. Peek e a -> Peek e a
cleanup forall a b. (a -> b) -> a -> b
$ do
forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. LuaError e => Int -> String -> LuaE e ()
checkstack' Int
2 String
"retrieving key-value pairs"
StackIndex
idx' <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. StackIndex -> LuaE e StackIndex
absindex StackIndex
idx
let remainingPairs :: Peek e [(a, b)]
remainingPairs = forall e a b. Peeker e a -> Peeker e b -> Peeker e (Maybe (a, b))
nextPair Peeker e a
keyPeeker Peeker e b
valuePeeker StackIndex
idx' forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (a, b)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return []
Just (a, b)
a -> ((a, b)
aforall a. a -> [a] -> [a]
:) forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Peek e [(a, b)]
remainingPairs
forall e a. LuaE e a -> Peek e a
liftLua forall e. LuaE e ()
pushnil
Peek e [(a, b)]
remainingPairs
nextPair :: Peeker e a -> Peeker e b -> Peeker e (Maybe (a, b))
nextPair :: forall e a b. Peeker e a -> Peeker e b -> Peeker e (Maybe (a, b))
nextPair Peeker e a
keyPeeker Peeker e b
valuePeeker StackIndex
idx = forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"key-value pair" forall a b. (a -> b) -> a -> b
$ do
Bool
hasNext <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. StackIndex -> LuaE e Bool
Unsafe.next StackIndex
idx
if Bool -> Bool
not Bool
hasNext
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
else do
a
key <- forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"key" forall a b. (a -> b) -> a -> b
$ Peeker e a
keyPeeker (CInt -> StackIndex
nth CInt
2)
b
value <- forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"value" forall a b. (a -> b) -> a -> b
$ Peeker e b
valuePeeker (CInt -> StackIndex
nth CInt
1)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (a
key, b
value))
forall e a b. Peek e a -> LuaE e b -> Peek e a
`lastly` forall e. Int -> LuaE e ()
pop Int
1
peekSet :: (LuaError e, Ord a) => Peeker e a -> Peeker e (Set a)
peekSet :: forall e a. (LuaError e, Ord a) => Peeker e a -> Peeker e (Set a)
peekSet Peeker e a
elementPeeker = forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"Set"
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Ord a => [a] -> Set a
Set.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a, b) -> b
snd)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a b.
LuaError e =>
Peeker e a -> Peeker e b -> Peeker e [(a, b)]
peekKeyValuePairs Peeker e a
elementPeeker forall e. Peeker e Bool
peekBool
peekFieldRaw :: LuaError e => Peeker e a -> Name -> Peeker e a
peekFieldRaw :: forall e a. LuaError e => Peeker e a -> Name -> Peeker e a
peekFieldRaw Peeker e a
peeker Name
name StackIndex
idx =
forall e a. Name -> Peek e a -> Peek e a
retrieving (Name
"raw field '" forall a. Semigroup a => a -> a -> a
<> Name
name forall a. Semigroup a => a -> a -> a
<> Name
"'") forall a b. (a -> b) -> a -> b
$! do
forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ do
forall e. LuaError e => Int -> String -> LuaE e ()
checkstack' Int
1 String
"peekFieldRaw"
StackIndex
absidx <- forall e. StackIndex -> LuaE e StackIndex
Lua.absindex StackIndex
idx
forall e. ByteString -> LuaE e ()
pushstring forall a b. (a -> b) -> a -> b
$ Name -> ByteString
fromName Name
name
forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall e. LuaError e => StackIndex -> LuaE e Type
rawget StackIndex
absidx)
Peeker e a
peeker StackIndex
top forall e a b. Peek e a -> LuaE e b -> Peek e a
`lastly` forall e. Int -> LuaE e ()
Lua.pop Int
1
{-# INLINABLE peekFieldRaw #-}
peekIndexRaw :: LuaError e => Lua.Integer -> Peeker e a -> Peeker e a
peekIndexRaw :: forall e a. LuaError e => Integer -> Peeker e a -> Peeker e a
peekIndexRaw Integer
i Peeker e a
peeker StackIndex
idx = do
let showInt :: Integer -> a
showInt (Lua.Integer Int64
x) = forall a. IsString a => String -> a
fromString forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Int64
x
forall e a. Name -> Peek e a -> Peek e a
retrieving (forall a. IsString a => String -> a
fromString forall a b. (a -> b) -> a -> b
$ String
"raw index '" forall a. Semigroup a => a -> a -> a
<> forall {a}. IsString a => Integer -> a
showInt Integer
i forall a. Semigroup a => a -> a -> a
<> String
"'") forall a b. (a -> b) -> a -> b
$! do
forall e a. LuaE e a -> Peek e a
liftLua forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
rawgeti StackIndex
idx Integer
i
Peeker e a
peeker StackIndex
top forall e a b. Peek e a -> LuaE e b -> Peek e a
`lastly` forall e. Int -> LuaE e ()
Lua.pop Int
1
{-# INLINABLE peekIndexRaw #-}
peekPair :: LuaError e
=> Peeker e a -> Peeker e b
-> Peeker e (a, b)
peekPair :: forall e a b.
LuaError e =>
Peeker e a -> Peeker e b -> Peeker e (a, b)
peekPair Peeker e a
peekA Peeker e b
peekB StackIndex
idx = forall e a. Peek e a -> Peek e a
cleanup forall a b. (a -> b) -> a -> b
$ do
forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. LuaError e => Int -> String -> LuaE e ()
checkstack' Int
2 String
"retrieving a pair"
StackIndex
idx' <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. StackIndex -> LuaE e StackIndex
absindex StackIndex
idx
a
a <- forall e a. LuaE e a -> Peek e a
liftLua (forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
rawgeti StackIndex
idx' Integer
1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker e a
peekA StackIndex
top
b
b <- forall e a. LuaE e a -> Peek e a
liftLua (forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
rawgeti StackIndex
idx' Integer
2) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker e b
peekB StackIndex
top
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, b
b)
peekTriple :: LuaError e
=> Peeker e a -> Peeker e b -> Peeker e c
-> Peeker e (a, b, c)
peekTriple :: forall e a b c.
LuaError e =>
Peeker e a -> Peeker e b -> Peeker e c -> Peeker e (a, b, c)
peekTriple Peeker e a
peekA Peeker e b
peekB Peeker e c
peekC StackIndex
idx = forall e a. Peek e a -> Peek e a
cleanup forall a b. (a -> b) -> a -> b
$ do
forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. LuaError e => Int -> String -> LuaE e ()
checkstack' Int
3 String
"retrieving a triple"
StackIndex
idx' <- forall e a. LuaE e a -> Peek e a
liftLua forall a b. (a -> b) -> a -> b
$ forall e. StackIndex -> LuaE e StackIndex
absindex StackIndex
idx
a
a <- forall e a. LuaE e a -> Peek e a
liftLua (forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
rawgeti StackIndex
idx' Integer
1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker e a
peekA StackIndex
top
b
b <- forall e a. LuaE e a -> Peek e a
liftLua (forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
rawgeti StackIndex
idx' Integer
2) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker e b
peekB StackIndex
top
c
c <- forall e a. LuaE e a -> Peek e a
liftLua (forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
rawgeti StackIndex
idx' Integer
3) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker e c
peekC StackIndex
top
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,b
b,c
c)
choice :: LuaError e
=> [Peeker e a]
-> Peeker e a
choice :: forall e a. LuaError e => [Peeker e a] -> Peeker e a
choice [Peeker e a]
peekers StackIndex
idx = case [Peeker e a]
peekers of
[] -> forall a e. ByteString -> Peek e a
failPeek ByteString
"all choices failed"
Peeker e a
p:[Peeker e a]
ps -> Peeker e a
p StackIndex
idx forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall e a. LuaError e => [Peeker e a] -> Peeker e a
choice [Peeker e a]
ps StackIndex
idx
{-# INLINABLE choice #-}