diff options
Diffstat (limited to 'src/lua')
| -rw-r--r-- | src/lua/evalsto.rs | 85 | ||||
| -rw-r--r-- | src/lua/mod.rs | 33 | ||||
| -rw-r--r-- | src/lua/runtime.rs | 9 |
3 files changed, 115 insertions, 12 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), + } + } +} diff --git a/src/lua/mod.rs b/src/lua/mod.rs index 7388890..fe3555e 100644 --- a/src/lua/mod.rs +++ b/src/lua/mod.rs @@ -1,5 +1,4 @@ use std::{ - borrow::Borrow, path::Path, sync::{Mutex, MutexGuard}, }; @@ -7,8 +6,9 @@ use std::{ use lazy_static::lazy_static; use mlua::prelude::*; -use crate::{config::GlobalConfig, sheet::cell::CellRef}; +use crate::{config::{theme::{sheetview::SheetViewTheme, Theme}, GlobalConfig}, sheet::cell::CellRef, state::{sheetview::SheetViewState, GlobalState}}; +pub mod evalsto; pub mod iobuffer; pub mod ownedfunction; pub mod runtime; @@ -32,18 +32,33 @@ lazy_static! { }; } +macro_rules! ud_is_type { + ($writer:ident, $ud:ident, $f:ty => $fe:expr $(, $($r:ty => $e:expr),+)? $(,)?) => { + if $ud.is::<$f>() { + $writer.write(format!("{:#?}", $fe)) + } $($( else if $ud.is::<$r>() { + $writer.write(format!("{:#?}", $e)) + })*)? else { + $writer.write(format!("{:#?}", $ud)); + } + }; +} + fn print(_: &Lua, args: LuaMultiValue) -> LuaResult<()> { let mut writer = iobuffer::iobuffer().write().unwrap(); for (i, arg) in args.iter().enumerate() { if let Some(ud) = arg.as_userdata() { - if ud.is::<CellRef>() { - writer.write(ud.borrow::<CellRef>().unwrap().value().to_string()); - } else if ud.is::<GlobalConfig>() { - writer.write(format!("{:#?}", GlobalConfig::instance().borrow())) - } else { - writer.write(format!("{:#?}", ud)); - } + ud_is_type!( + writer, + ud, + CellRef => ud.borrow::<CellRef>(), + GlobalConfig => GlobalConfig::instance(), + Theme => GlobalConfig::instance().theme, + SheetViewTheme => GlobalConfig::instance().theme.sheetview, + GlobalState => GlobalState::instance(), + SheetViewState => GlobalState::instance().sheetview, + ); } else { writer.write(format!("{:#?}", arg)); } diff --git a/src/lua/runtime.rs b/src/lua/runtime.rs index dfb37e6..4e8c52b 100644 --- a/src/lua/runtime.rs +++ b/src/lua/runtime.rs @@ -3,17 +3,20 @@ use std::time::{SystemTime, UNIX_EPOCH}; use crate::{ config::{self, GlobalConfig}, - sheet::register::Register, + sheet::register::Register, state::GlobalState, }; pub fn neosheet(lua: &Lua) -> Result<()> { let exports = lua.create_table()?; exports - .set("sheets", lua.create_proxy::<Register>()?) + .set("sheets", lua.create_userdata(Register)?) .unwrap(); exports - .set("config", lua.create_userdata(GlobalConfig::new())?) + .set("config", lua.create_userdata(GlobalConfig::default())?) + .unwrap(); + exports + .set("state", lua.create_userdata(GlobalState::default())?) .unwrap(); lua.globals() |