use std::sync::atomic::{AtomicUsize, Ordering}; use diaphragm_core::{ solving::VariableHandle, text::{FontDescription as CoreFontDescription, FontStyle, FontWeight, Text as CoreText}, types::Float as CoreFloat, }; // use diaphragm_cairo_renderer::CairoRenderer; // use diaphragm_core::Runtime; // use diaphragm_z3_solver::{z3, Z3Context}; use mlua::prelude::*; static MAX_ID: AtomicUsize = AtomicUsize::new(0); #[derive(Clone, Copy, Debug)] struct Float(CoreFloat); impl Float { fn new() -> Float { Float(CoreFloat::Variable(VariableHandle::new( MAX_ID.fetch_add(1, Ordering::SeqCst), ))) } } impl LuaUserData for Float {} fn float(_: &Lua, _: ()) -> LuaResult { Ok(Float::new()) } #[derive(Clone, Debug)] struct FontDescription(CoreFontDescription); impl LuaUserData for FontDescription {} const DEFAULT_FONT_FAMILY: &str = "serif"; impl Default for FontDescription { fn default() -> Self { Self(CoreFontDescription { family: DEFAULT_FONT_FAMILY.to_string(), style: FontStyle::Normal, weight: FontWeight::Normal, size: Float::new().0, }) } } fn font(_: &Lua, params: LuaTable) -> LuaResult { // TODO: better validation of the table // What happens when I mistype a param? // TODO: better error handling let family = params .get::<_, Option<_>>("family")? .unwrap_or_else(|| DEFAULT_FONT_FAMILY.to_string()); let style = match params.get::<_, Option>("style")?.as_deref() { Some("normal") | None => FontStyle::Normal, Some(_) => return Err(LuaError::RuntimeError("Unknown style".to_string())), }; let weight = match params.get::<_, Option>("weight")?.as_deref() { Some("normal") | None => FontWeight::Normal, Some(_) => return Err(LuaError::RuntimeError("Unknown weight".to_string())), }; let size = params .get::<_, Option<_>>("size")? .unwrap_or_else(Float::new); Ok(FontDescription(CoreFontDescription { family, style, weight, size: size.0, })) } #[derive(Clone, Debug)] struct Text(CoreText); impl LuaUserData for Text {} fn text(_: &Lua, params: LuaTable) -> LuaResult { let content = params.get("content")?; let font = params .get::<_, Option>("font")? .unwrap_or_default(); Ok(Text(CoreText { content, font: font.0, })) } fn draw(_: &Lua, params: LuaTable) -> LuaResult<()> { let content: LuaTable = params.get("content")?; let output: LuaTable = params.get("output")?; dbg!(content, output); Ok(()) } #[mlua::lua_module] fn libdiaphragm(lua: &Lua) -> LuaResult { // TODO: the solver as a mutable global solves so much problem (pun not intended) let exports = lua.create_table()?; exports.set("text", lua.create_function(text)?)?; exports.set("font", lua.create_function(font)?)?; exports.set("float", lua.create_function(float)?)?; exports.set("draw", lua.create_function(draw)?)?; Ok(exports) }