hex_patch/app/plugins/
register_userdata.rs

1use mlua::{FromLua, IntoLua, Lua, Table, UserDataFields, UserDataMethods};
2use ratatui::{
3    layout::Alignment,
4    text::{Span, Text},
5};
6
7use crate::app::settings::{
8    app_settings::AppSettings, color_settings::ColorSettings, key_settings::KeySettings,
9    register_color_settings_macro::set_style, settings_value::SettingsValue, Settings,
10};
11
12pub fn register_vec_u8(lua: &Lua) -> mlua::Result<()> {
13    lua.register_userdata_type(|data: &mut mlua::UserDataRegistry<Vec<u8>>| {
14        data.add_field_method_get("len", |_lua, this| Ok(this.len()));
15        data.add_method("get", |_lua, this, index: usize| {
16            if let Some(byte) = this.get(index) {
17                Ok(*byte)
18            } else {
19                Err(mlua::Error::RuntimeError("Index out of bounds".to_string()))
20            }
21        });
22        data.add_method_mut("set", |_lua, this, (index, value): (usize, u8)| {
23            if let Some(byte) = this.get_mut(index) {
24                let old_value = *byte;
25                *byte = value;
26                Ok(old_value)
27            } else {
28                Err(mlua::Error::RuntimeError("Index out of bounds".to_string()))
29            }
30        });
31    })?;
32    Ok(())
33}
34
35pub fn register_text(lua: &Lua) -> mlua::Result<()> {
36    lua.register_userdata_type(|data: &mut mlua::UserDataRegistry<Text>| {
37        data.add_method_mut("push_line", |_lua, this, value: String| {
38            let span = Span::styled(value, this.style);
39            let line = match &this.alignment {
40                Some(alignment) => match alignment {
41                    Alignment::Left => span.into_left_aligned_line(),
42                    Alignment::Center => span.into_centered_line(),
43                    Alignment::Right => span.into_right_aligned_line(),
44                },
45                None => span.into(),
46            };
47            this.push_line(line);
48            Ok(())
49        });
50        data.add_method_mut("push_span", |_lua, this, value: String| {
51            this.push_span(Span::styled(value, this.style));
52            Ok(())
53        });
54        data.add_method_mut("set_style", |lua, this, value: Table| {
55            set_style(lua, &mut this.style, value)
56        });
57        data.add_method_mut("reset_style", |_lua, this, ()| {
58            this.style = Default::default();
59            Ok(())
60        });
61        data.add_method_mut("set_alignment", |_lua, this, value: String| {
62            match value.as_str() {
63                "left" => this.alignment = Some(Alignment::Left),
64                "center" => this.alignment = Some(Alignment::Center),
65                "right" => this.alignment = Some(Alignment::Right),
66                _ => return Err(mlua::Error::RuntimeError("Invalid alignment".to_string())),
67            }
68            Ok(())
69        });
70        data.add_method_mut("reset_alignment", |_lua, this, ()| {
71            this.alignment = None;
72            Ok(())
73        });
74    })?;
75    Ok(())
76}
77
78pub fn register_string(lua: &Lua) -> mlua::Result<()> {
79    lua.register_userdata_type(|data: &mut mlua::UserDataRegistry<String>| {
80        data.add_method("get", |_lua, this, ()| Ok(this.clone()));
81        data.add_method_mut("set", |_lua, this, value: String| {
82            let old_value = std::mem::replace(this, value);
83            Ok(old_value)
84        });
85    })?;
86    Ok(())
87}
88
89pub fn register_usize(lua: &Lua) -> mlua::Result<()> {
90    lua.register_userdata_type(|data: &mut mlua::UserDataRegistry<usize>| {
91        data.add_method("get", |_lua, this, ()| Ok(*this));
92        data.add_method_mut("set", |_lua, this, value: usize| {
93            let old_value = std::mem::replace(this, value);
94            Ok(old_value)
95        });
96    })?;
97    Ok(())
98}
99
100pub fn register_settings(lua: &Lua) -> mlua::Result<()> {
101    lua.register_userdata_type(|data: &mut mlua::UserDataRegistry<Settings>| {
102        ColorSettings::register_userdata(data);
103        KeySettings::register_userdata(data);
104        AppSettings::register_userdata(data);
105        data.add_method("get_custom", |_lua, this, key: String| {
106            Ok(this.custom.get(&key).cloned())
107        });
108        data.add_method_mut(
109            "set_custom",
110            |lua, this, (key, value): (String, mlua::Value)| {
111                if let Some(old_value) = this.custom.get_mut(&key) {
112                    let old_value_copy = old_value.clone();
113                    if value.is_nil() {
114                        this.custom.remove(&key);
115                    } else {
116                        *old_value = SettingsValue::from_lua(value, lua)?;
117                    }
118                    old_value_copy.into_lua(lua)
119                } else {
120                    if !value.is_nil() {
121                        this.custom
122                            .insert(key, SettingsValue::from_lua(value, lua)?);
123                    }
124                    Ok(mlua::Value::Nil)
125                }
126            },
127        );
128    })?;
129    Ok(())
130}