Move eval_error onto FennelError as from_lua
The free function constructed a FennelError::Eval, so it belonged on
the type. extract_line_offset and line_offset are private helpers
again.

Assisted-by: GLM-5.1 via pi
change ymvnqzmoszlpsplmpnpulxxqkxpsotmk
commit b2c26dc5c4e819ff13e368a30094dbde07736784
author Alpha Chen <alpha@kejadlen.dev>
date
parent krmnnzpx
diff --git a/src/ci.rs b/src/ci.rs
index e0bb90a..aaba216 100644
--- a/src/ci.rs
+++ b/src/ci.rs
@@ -318,7 +318,7 @@ pub fn eval_ci(
         // Convert mlua errors into rich FennelError with source snippets.
         match e {
             mlua::Error::RuntimeError(_) | mlua::Error::SyntaxError { .. } => {
-                crate::fennel::eval_error(source, name, &e).into()
+                crate::fennel::FennelError::from_lua(source, name, &e).into()
             }
             _ => crate::Error::Fennel(crate::fennel::FennelError::Eval {
                 message: format!("{name}: {e}"),
diff --git a/src/fennel.rs b/src/fennel.rs
index e6459e4..b0518eb 100644
--- a/src/fennel.rs
+++ b/src/fennel.rs
@@ -121,7 +121,7 @@ impl Fennel {
 
         let result = eval
             .call::<mlua::Value>((source, opts))
-            .map_err(|e| eval_error(source, name, &e))?;
+            .map_err(|e| FennelError::from_lua(source, name, &e))?;
 
         // Reject nil results — a config file that evaluates to nothing is
         // almost always a mistake.
@@ -151,18 +151,22 @@ impl Fennel {
     }
 }
 
-pub(crate) fn eval_error(source: &str, name: &str, err: &mlua::Error) -> FennelError {
-    let message = format!("{name}: {err}");
+impl FennelError {
+    /// Construct an `Eval` error from an mlua error, extracting line
+    /// information when available.
+    pub(crate) fn from_lua(source: &str, name: &str, err: &mlua::Error) -> Self {
+        let message = format!("{name}: {err}");
 
-    // Try to extract a line number from the Lua error for a label.
-    let offset = extract_line_offset(err)
-        .and_then(|line| line_offset(source, line))
-        .unwrap_or(SourceOffset::from(0));
+        // Try to extract a line number from the Lua error for a label.
+        let offset = extract_line_offset(err)
+            .and_then(|line| line_offset(source, line))
+            .unwrap_or(SourceOffset::from(0));
 
-    FennelError::Eval {
-        message,
-        source_code: source.to_string(),
-        label: offset,
+        FennelError::Eval {
+            message,
+            source_code: source.to_string(),
+            label: offset,
+        }
     }
 }
 
@@ -172,7 +176,7 @@ pub(crate) fn eval_error(source: &str, name: &str, err: &mlua::Error) -> FennelE
 /// The name may contain colons (e.g. `HEAD:.quire/config.fnl`), so splitting
 /// from the left breaks. Match the first `:LINE:COLUMN: ` run, which is
 /// unambiguous — filenames don't end with `:digits:digits:`.
-pub(crate) fn extract_line_offset(err: &mlua::Error) -> Option<usize> {
+fn extract_line_offset(err: &mlua::Error) -> Option<usize> {
     let msg = err.to_string();
     let re = regex::Regex::new(r":(\d+):\d+: ").ok()?;
     let caps = re.captures(&msg)?;
@@ -184,7 +188,7 @@ pub(crate) fn extract_line_offset(err: &mlua::Error) -> Option<usize> {
 }
 
 /// Convert a 1-based line number to a byte offset in the source.
-pub(crate) fn line_offset(source: &str, line: usize) -> Option<SourceOffset> {
+fn line_offset(source: &str, line: usize) -> Option<SourceOffset> {
     if line == 0 {
         return None;
     }