use std::{ path::Path, sync::{Mutex, MutexGuard}, }; use lazy_static::lazy_static; use mlua::prelude::*; use crate::{ config::{ theme::{sheetview::SheetViewTheme, Theme}, GlobalConfig, }, sheet::cell::CellRef, state::{view::SheetViewState, GlobalState}, }; pub mod evalsto; pub mod iobuffer; pub mod ownedfunction; pub mod runtime; lazy_static! { static ref LUA: Mutex = { let lock = Mutex::new(Lua::new()); { let lua = lock.lock().unwrap(); let print_binding = lua.create_function(print).unwrap(); lua.globals().set("print", print_binding).unwrap(); runtime::math(&lua).unwrap(); runtime::neosheet(&lua).unwrap(); runtime::package(&lua).unwrap(); } lock }; } 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() { ud_is_type!( writer, ud, CellRef => ud.borrow::(), GlobalConfig => GlobalConfig::instance(), Theme => GlobalConfig::instance().theme, SheetViewTheme => GlobalConfig::instance().theme.sheetview, GlobalState => GlobalState::instance(), SheetViewState => GlobalState::instance().sheetview, ); } else { writer.write(format!("{:#?}", arg)); } if i < args.len() - 1 { writer.write(", "); } } writer.writeln(""); Ok(()) } pub fn get() -> MutexGuard<'static, Lua> { LUA.lock().unwrap() } pub fn source(path: &str) -> LuaResult<()> { let path = Path::new(path); if path.exists() && path.is_file() { get().load(path).exec()?; Ok(()) } else { Err(LuaError::runtime(format!( "could not source {:?} (file not found)", path ))) } }