aboutsummaryrefslogtreecommitdiffstats
path: root/src/theming/lua.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/theming/lua.rs')
-rw-r--r--src/theming/lua.rs39
1 files changed, 27 insertions, 12 deletions
diff --git a/src/theming/lua.rs b/src/theming/lua.rs
index c9168cb..6bd6989 100644
--- a/src/theming/lua.rs
+++ b/src/theming/lua.rs
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-only
use std::sync::LazyLock;
-use std::ops::Deref;
use std::path::Path;
+use std::fs;
-use tokio::sync::Mutex;
-use mlua::{Lua, Compiler, StdLib, Value, LuaOptions};
+use std::sync::Mutex;
+use mlua::{Lua, LuaSerdeExt, Compiler, StdLib, Value, LuaOptions, Table};
use http::StatusCode;
use crate::CONFIG;
@@ -37,16 +37,19 @@ static LUA: LazyLock<Mutex<Lua>> = LazyLock::new(|| {
let themes = lua.create_table().expect("creating themes table");
for (k, v) in INTERNAL_THEMES {
+ log::info!("Registering compiled lua theme `{k}`.");
let _ = themes.set(*k, lua.load(*v).into_function().expect("loading internal theme"));
}
if let Some(theme_dir) = CONFIG.theme_dir.as_ref() {
+ log::info!("Registering lua theme dir `{theme_dir}` with extension `{}`.", CONFIG.theme_ext_lua);
for (k, v) in walk_dir(theme_dir.as_ref().as_ref()).expect("walking theme dir") {
- let _ = themes.set(k, lua.load(v).into_function().expect("loading internal theme"));
+ log::info!("Registering runtime lua theme `{k}`.");
+ let _ = themes.set(k, lua.load(v).eval::<Value>().expect("loading internal theme"));
}
}
- let _ = lua.globals().set("__themes", themes).unwrap();
+ lua.globals().set("__themes", themes).unwrap();
lua.globals().set_readonly(true);
@@ -54,7 +57,7 @@ static LUA: LazyLock<Mutex<Lua>> = LazyLock::new(|| {
});
fn walk_dir(path: &Path) -> std::io::Result<Vec<(String, String)>> {
- use std::fs;
+ let ext = CONFIG.theme_ext_lua.as_ref();
let mut path_bits = vec![];
let mut dir_readers = vec![fs::read_dir(path)?];
@@ -67,7 +70,7 @@ fn walk_dir(path: &Path) -> std::io::Result<Vec<(String, String)>> {
let name = ent.file_name().into_string().expect("why do you have such FUCKED UP FILE PATHS");
let ty = ent.file_type()?;
if ty.is_file() && name.ends_with(CONFIG.theme_ext_lua.as_ref()) {
- ret.push((path_bits.join("") + &name, fs::read_to_string(ent.path())?));
+ ret.push((path_bits.join("") + &name[..name.len() - ext.len()], fs::read_to_string(ent.path())?));
}
else if ty.is_dir() {
path_bits.push(name);
@@ -82,10 +85,22 @@ fn walk_dir(path: &Path) -> std::io::Result<Vec<(String, String)>> {
Ok(ret)
}
-pub fn touch() {
- let _ = LUA.deref();
-}
-
pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String, StatusCode>> {
- return None
+ LUA.clear_poison();
+ let lua = LUA.lock().expect("FIXME: Mutex poisoning race condition.");
+ let themes: Table = lua.globals().get("__themes").unwrap();
+ let Ok(Value::Function(theme)) = themes.get(name)
+ else {
+ return None;
+ };
+
+ let ctx = match lua.to_value(ctx) {
+ Ok(ok) => ok,
+ Err(e) => {
+ log::error!("Lua context serialization error: {e}");
+ return Some(Err(StatusCode::INTERNAL_SERVER_ERROR))
+ }
+ };
+
+ Some(theme.call((ctx,)).map_err(|e| { log::error!("Lua theme execution error: {e}"); StatusCode::INTERNAL_SERVER_ERROR }))
}