use crate::lua::{self, Result, Value, ffi, private::Sealed};
pub trait ToLua: Sized {
fn push_to_stack(self, l: &lua::State);
fn to_value(self, l: &lua::State) -> Value {
self.push_to_stack(l); Value::pop_from_stack(l)
}
fn stack_count() -> i32 {
1
}
}
pub trait FromLua: Sized {
fn try_from_stack(l: &lua::State, index: i32) -> Result<Self>;
fn try_from_value(value: Value, _: &lua::State) -> Result<Self> {
Self::try_from_stack(&value.ref_state(), value.index())
}
}
pub trait ToLuaMulti: Sized {
fn push_to_stack_multi(self, l: &lua::State);
fn push_to_stack_multi_count(self, l: &lua::State) -> i32 {
let base = ffi::lua_gettop(l.0);
self.push_to_stack_multi(l);
ffi::lua_gettop(l.0) - base
}
}
impl<T: ToLua> ToLuaMulti for T {
fn push_to_stack_multi(self, l: &lua::State) {
self.push_to_stack(l);
}
fn push_to_stack_multi_count(self, l: &lua::State) -> i32 {
self.push_to_stack(l);
T::stack_count()
}
}
pub trait FromLuaMulti: Sized {
fn try_from_stack_multi(l: &lua::State, start_index: i32, count: i32) -> Result<(Self, i32)>;
}
impl<T: FromLua> FromLuaMulti for T {
fn try_from_stack_multi(l: &lua::State, start_index: i32, _: i32) -> Result<(Self, i32)> {
T::try_from_stack(l, start_index).map(|v| (v, 1))
}
}
pub trait ObjectLike: Sealed {
fn get<V: FromLua>(&self, l: &lua::State, key: impl ToLua) -> Result<V>;
fn set(&self, l: &lua::State, key: impl ToLua, value: impl ToLua) -> Result<()>;
fn call<R: FromLuaMulti>(
&self,
l: &lua::State,
name: &str,
args: impl ToLuaMulti,
) -> lua::Result<R>;
fn call_method<R: FromLuaMulti>(
&self,
l: &lua::State,
name: &str,
args: impl ToLuaMulti,
) -> lua::Result<R>;
}