summaryrefslogtreecommitdiff
path: root/src/lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua')
-rw-r--r--src/lua/evalsto.rs85
-rw-r--r--src/lua/mod.rs33
-rw-r--r--src/lua/runtime.rs9
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()