use std::borrow::Cow;
use mlua::{FromLuaMulti, Lua, MetaMethod, Result, ToLua, ToLuaMulti};
use crate::{TealMultiValue, TypeName};
use super::MaybeSend;
pub trait TealDataMethods<'lua, T: TypeName> {
fn add_method<S, A, R, M>(&mut self, name: &S, method: M)
where
S: ?Sized + AsRef<[u8]>,
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> Result<R>;
fn add_method_mut<S, A, R, M>(&mut self, name: &S, method: M)
where
S: ?Sized + AsRef<[u8]>,
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> Result<R>;
#[cfg(feature = "mlua_async")]
fn add_async_method<S: ?Sized, A, R, M, MR>(&mut self, name: &S, method: M)
where
T: Clone,
S: AsRef<[u8]>,
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
M: 'static + MaybeSend + Fn(&'lua Lua, T, A) -> MR,
MR: 'lua + std::future::Future<Output = Result<R>>;
fn add_function<S, A, R, F>(&mut self, name: &S, function: F)
where
S: ?Sized + AsRef<[u8]>,
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
F: 'static + MaybeSend + Fn(&'lua Lua, A) -> Result<R>;
fn add_function_mut<S, A, R, F>(&mut self, name: &S, function: F)
where
S: ?Sized + AsRef<[u8]>,
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> Result<R>;
#[cfg(feature = "mlua_async")]
fn add_async_function<S: ?Sized, A, R, F, FR>(&mut self, name: &S, function: F)
where
S: AsRef<[u8]>,
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
F: 'static + MaybeSend + Fn(&'lua Lua, A) -> FR,
FR: 'lua + std::future::Future<Output = Result<R>>;
fn add_meta_method<A, R, M>(&mut self, meta: MetaMethod, method: M)
where
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> Result<R>;
fn add_meta_method_mut<A, R, M>(&mut self, meta: MetaMethod, method: M)
where
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> Result<R>;
fn add_meta_function<A, R, F>(&mut self, meta: MetaMethod, function: F)
where
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
F: 'static + MaybeSend + Fn(&'lua Lua, A) -> Result<R>;
fn add_meta_function_mut<A, R, F>(&mut self, meta: MetaMethod, function: F)
where
A: FromLuaMulti<'lua> + TealMultiValue,
R: ToLuaMulti<'lua> + TealMultiValue,
F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> Result<R>;
fn document(&mut self, documentation: &str) -> &mut Self;
fn document_type(&mut self, documentation: &str) -> &mut Self;
fn generate_help(&mut self);
}
pub trait InstanceCollector<'lua> {
fn add_instance<P, T, F>(&mut self, global_name: P, instance: F) -> Result<&mut Self>
where
P: Into<Cow<'static, str>>,
T: TypeName + ToLua<'lua>,
F: FnOnce(&'lua mlua::Lua) -> mlua::Result<T>;
fn document_instance(&mut self, doc: &'static str) -> &mut Self;
}
pub fn set_global_env<T: ExportInstances>(env: T, lua: &mlua::Lua) -> Result<()> {
let globals = lua.globals();
env.add_instances(&mut (globals, lua))?;
Ok(())
}
impl<'lua> InstanceCollector<'lua> for (mlua::Table<'lua>, &'lua mlua::Lua) {
fn add_instance<P, T, F>(&mut self, global_name: P, instance: F) -> Result<&mut Self>
where
P: Into<Cow<'static, str>>,
T: TypeName + ToLua<'lua>,
F: FnOnce(&'lua mlua::Lua) -> Result<T>,
{
let instance = instance(self.1)?;
self.0.set(global_name.into(), instance)?;
Ok(self)
}
fn document_instance(&mut self, _: &'static str) -> &mut Self {
self
}
}
pub trait ExportInstances: Default {
fn add_instances<'lua, T: InstanceCollector<'lua>>(
self,
instance_collector: &mut T,
) -> Result<()>;
}