diff options
Diffstat (limited to 'src/lua/evalsto.rs')
| -rw-r--r-- | src/lua/evalsto.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/lua/evalsto.rs b/src/lua/evalsto.rs new file mode 100644 index 0000000..6d8ab29 --- /dev/null +++ b/src/lua/evalsto.rs @@ -0,0 +1,85 @@ +use std::{fmt, marker::PhantomData, sync::Arc}; + +use mlua::{FromLua, IntoLua, Lua, Result, Value}; + +use crate::lua::ownedfunction::OwnedFunction; + +#[derive(Clone)] +pub enum EvalTo<T, A> { + Function(Arc<OwnedFunction>, PhantomData<A>), + Value(T), +} + +impl<T, A> EvalTo<T, A> { + pub fn get<'lua>(&'lua self, args: A, lua: &'lua Lua) -> Result<T> + where + T: FromLua<'lua> + Clone, + A: IntoLua<'lua>, + { + match self { + EvalTo::Function(value, _) => { + let func = value.get(lua); + T::from_lua(func.call(args)?, lua) + } + EvalTo::Value(value) => Ok(value.clone()), + } + } + + pub const fn new(value: T) -> Self { + Self::Value(value) + } +} + +impl<'lua, T, A> FromLua<'lua> for EvalTo<T, A> +where + T: FromLua<'lua> + Clone, + A: IntoLua<'lua>, +{ + fn from_lua( + value: mlua::prelude::LuaValue<'lua>, + lua: &'lua mlua::prelude::Lua, + ) -> Result<Self> { + if value.is_function() { + Ok(Self::Function( + Arc::new(OwnedFunction::new(value, lua)), + PhantomData, + )) + } else { + Ok(Self::Value(T::from_lua(value, lua)?)) + } + } +} + +impl<'lua, T, A> IntoLua<'lua> for EvalTo<T, A> +where + T: FromLua<'lua> + Clone + IntoLua<'lua>, + A: IntoLua<'lua>, +{ + fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> Result<Value<'lua>> { + match self { + EvalTo::Function(value, _) => Ok(value.get(lua).into_lua(lua)?), + EvalTo::Value(value) => value.into_lua(lua), + } + } +} + +impl<T, A> Default for EvalTo<T, A> +where + T: Default, +{ + fn default() -> Self { + Self::Value(T::default()) + } +} + +impl<T, A> fmt::Debug for EvalTo<T, A> +where + T: fmt::Debug +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + EvalTo::Function(_, _) => write!(f, "function"), + EvalTo::Value(v) => v.fmt(f), + } + } +} |