use mlua::prelude::*; use once_cell::sync::Lazy; use std::{path::Path, ptr::addr_of_mut}; use crate::{ config::{ theme::{view::SheetViewTheme, Theme}, GlobalConfig, }, sheet::cell::CellRef, state::{view::SheetViewState, GlobalState}, }; pub mod evalsto; pub mod iobuffer; pub mod ownedfunction; pub mod runnable; pub mod runtime; macro_rules! ud_is_type { ($content:ident, $ud:ident, $f:ty => $fe:expr $(, $($r:ty => $e:expr),+)? $(,)?) => { if $ud.is::<$f>() { $content += &format!("{:#?}", $fe); } $($( else if $ud.is::<$r>() { $content += &format!("{:#?}", $e); })*)? else { $content += &format!("{:#?}", $ud); } }; } fn print(_: &Lua, args: LuaMultiValue) -> LuaResult<()> { let mut writer = iobuffer::iobuffer().write().unwrap(); let mut content = String::new(); for (i, arg) in args.iter().enumerate() { if let Some(ud) = arg.as_userdata() { ud_is_type!( content, ud, CellRef => ud.borrow::(), GlobalConfig => GlobalConfig::get(), Theme => GlobalConfig::get().theme, SheetViewTheme => GlobalConfig::get().theme.view, GlobalState => GlobalState::get(), SheetViewState => GlobalState::get().view, ); } else { content += &format!("{:#?}", arg); } if i < args.len() - 1 { content += ", "; } } content += "\n"; writer.print(content); Ok(()) } pub fn get() -> &'static mut Lazy { static mut LUA: Lazy = Lazy::new(|| { let lua = Lua::new(); 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(); lua }); unsafe { &mut *addr_of_mut!(LUA) } } 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 ))) } } pub fn source_default_config() -> LuaResult<()> { get().load(include_str!("../init.lua")).exec() }