use std::borrow::Cow;
use rlua::{Context, FromLuaMulti, MetaMethod, Result, ToLua, ToLuaMulti};
use crate::{TealMultiValue, TypeName};
pub trait TealDataMethods<'lua, T> {
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 + Send + Fn(Context<'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 + Send + FnMut(Context<'lua>, &mut T, A) -> 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 + Send + Fn(Context<'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 + Send + FnMut(Context<'lua>, A) -> 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 + Send + Fn(Context<'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 + Send + FnMut(Context<'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 + Send + Fn(Context<'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 + Send + FnMut(Context<'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(Context<'lua>) -> rlua::Result<T>;
fn document_instance(&mut self, doc: &'static str) -> &mut Self;
}
pub fn set_global_env<T: ExportInstances>(env: T, context: rlua::Context) -> rlua::Result<()> {
let globals = context.globals();
env.add_instances::<_>(&mut (globals, context))?;
Ok(())
}
impl<'lua> InstanceCollector<'lua> for (rlua::Table<'lua>, rlua::Context<'lua>) {
fn add_instance<
P: Into<Cow<'static, str>>,
T: TypeName + ToLua<'lua>,
F: FnOnce(Context<'lua>) -> rlua::Result<T>,
>(
&mut self,
global_name: P,
instance: F,
) -> Result<&mut Self> {
let instance = instance(self.1)?;
self.0.set(global_name.into().to_string(), 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<()>;
}