summaryrefslogtreecommitdiffstats
path: root/lua-bindings/src/lib.rs
blob: 6628ee2e210718125eb12585da26df8cc25e5f47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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<Float> {
    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<FontDescription> {
    // 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<String>>("style")?.as_deref() {
        Some("normal") | None => FontStyle::Normal,
        Some(_) => return Err(LuaError::RuntimeError("Unknown style".to_string())),
    };

    let weight = match params.get::<_, Option<String>>("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<Text> {
    let content = params.get("content")?;

    let font = params
        .get::<_, Option<FontDescription>>("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<LuaTable> {
    // 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)
}