use std::ffi::c_void;
use crate::{FromLua, FromLuaMulti, IntoLua, LuaFunctionRef, LuaResult, LuaValue};
#[derive(Clone, Debug)]
pub struct LuaFunction {
pub(crate) inner: LuaFunctionRef,
}
impl LuaFunction {
pub(crate) fn new(inner: LuaFunctionRef) -> Self {
LuaFunction { inner }
}
#[inline]
pub fn upvalue_count(&self) -> usize {
self.inner.upvalue_count()
}
#[inline]
pub fn get_upvalue<T: FromLua>(&self, n: usize) -> LuaResult<Option<(String, T)>> {
self.inner.get_upvalue(n)
}
#[inline]
pub fn set_upvalue<T: IntoLua>(&self, n: usize, value: T) -> LuaResult<Option<String>> {
self.inner.set_upvalue(n, value)
}
#[inline]
pub fn upvalue_id(&self, n: usize) -> Option<*mut c_void> {
self.inner.upvalue_id(n)
}
#[inline]
pub fn join_upvalue(&self, n1: usize, other: &LuaFunction, n2: usize) -> LuaResult<bool> {
self.inner.join_upvalue(n1, &other.inner, n2)
}
#[inline]
pub fn call<A: IntoLua, R: FromLuaMulti>(&self, args: A) -> LuaResult<R> {
self.inner.call(args)
}
#[inline]
pub fn call1<A: IntoLua, R: FromLua>(&self, args: A) -> LuaResult<R> {
self.inner.call1(args)
}
pub unsafe fn to_value(&self) -> LuaValue {
self.inner.to_value()
}
}
impl IntoLua for LuaFunction {
#[inline]
fn into_lua(self, state: &mut luars::LuaState) -> Result<usize, String> {
state
.push_value(self.inner.to_value())
.map_err(|e| format!("{:?}", e))?;
Ok(1)
}
}
impl IntoLua for &LuaFunction {
#[inline]
fn into_lua(self, state: &mut luars::LuaState) -> Result<usize, String> {
state
.push_value(self.inner.to_value())
.map_err(|e| format!("{:?}", e))?;
Ok(1)
}
}
impl FromLua for LuaFunction {
fn from_lua(value: LuaValue, state: &mut luars::LuaState) -> Result<Self, String> {
let actual = value.type_name();
let function = state
.to_function_ref(value)
.ok_or_else(|| format!("expected function, got {}", actual))?;
Ok(LuaFunction::new(function))
}
}