Convert config errors once at the load boundary
Assisted-by: GLM-5.3 via pi
change xlrynqkvsvututnvyrtzuuxrpzrmpzyz
commit 71aa4b8ae4c827808f3c7dacd5e7d10ba774fe70
author Alpha Chen <alpha@kejadlen.dev>
date
parent ypuunnsn
diff --git a/src/parallax.rs b/src/parallax.rs
index 1322b91..25a2a9f 100644
--- a/src/parallax.rs
+++ b/src/parallax.rs
@@ -54,28 +54,17 @@ impl Parallax {
         // safe default omits. Configs are the user's own trusted files,
         // so the full stdlib is fine here.
         let lua = unsafe { Lua::unsafe_new() };
-        let fail = |error: mlua::Error| Error::Config {
-            path: path.to_path_buf(),
-            error,
-        };
-
-        let fennel: Table = lua
-            .load(FENNEL_LUA)
-            .set_name("fennel.lua")
-            .eval()
-            .map_err(fail)?;
-
         let stash = Arc::new(Mutex::new(Registrations::default()));
-        install_module(&lua, &stash).map_err(fail)?;
-
         let filename = path.to_string_lossy().into_owned();
-        run_config(&lua, &fennel, &source, &filename).map_err(fail)?;
 
         let Registrations {
             setup,
             server,
             flows,
-        } = mem::take(&mut *lock(&stash).map_err(fail)?);
+        } = run_config(&lua, &source, &filename, &stash).map_err(|error| Error::Config {
+            path: path.to_path_buf(),
+            error,
+        })?;
 
         let setup = setup.ok_or_else(|| Error::ConfigRegistration {
             path: path.to_path_buf(),
@@ -229,12 +218,18 @@ fn caller_position(lua: &Lua) -> Option<String> {
     }
 }
 
+/// Loads the Fennel compiler, runs the config, and returns everything
+/// it registered. Every failure surfaces as an mlua error; the caller
+/// annotates it with the config's path.
 fn run_config(
     lua: &Lua,
-    fennel: &Table,
     source: &str,
     filename: &str,
-) -> Result<Value, mlua::Error> {
+    stash: &Arc<Mutex<Registrations>>,
+) -> Result<Registrations, mlua::Error> {
+    let fennel: Table = lua.load(FENNEL_LUA).set_name("fennel.lua").eval()?;
+    install_module(lua, stash)?;
+
     // Configs end with a registration call, which compiles to a tail
     // call; tail elimination destroys the config's stack frame, hiding
     // the call site from registration errors. Turning the final return
@@ -251,7 +246,11 @@ fn run_config(
     options.set("correlate", true)?;
     let compiled: String = compile.call((source, options))?;
     let compiled = protect_tail_call(&compiled);
-    lua.load(compiled).set_name(format!("@{filename}")).eval()
+    lua.load(compiled)
+        .set_name(format!("@{filename}"))
+        .eval::<()>()?;
+
+    Ok(mem::take(&mut *lock(stash)?))
 }
 
 // The index arithmetic in this helper is safe because `index` comes from