use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn format_validation_error(
code: &str,
file_path: &str,
error_kind: &str,
line_num: usize,
col_num: usize,
message: &str,
help: &str,
underline_length: usize,
) -> String {
format_error_impl(code, file_path, error_kind, line_num, col_num, message, help, underline_length)
}
fn format_error_impl(
code: &str,
file_path: &str,
error_kind: &str,
line_num: usize,
col_num: usize,
message: &str,
help: &str,
underline_length: usize,
) -> String {
let lines: Vec<&str> = code.lines().collect();
let error_line = if line_num > 0 && line_num <= lines.len() {
lines[line_num - 1]
} else {
""
};
let underline_length = underline_length.max(1);
format!(
"\nValidation Error\n\
❌ {}\n\
\n\
┌─ {}:{}:{}\n\
│\n\
{:>3} │ {}\n\
│ {}{} {}\n\
│\n\
= help: {}\n\
│\n\
└─\n",
error_kind,
file_path,
line_num,
col_num,
line_num,
error_line,
" ".repeat(col_num.saturating_sub(1)),
"^".repeat(underline_length),
message,
help
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_error_formatting() {
let code = "import { console } from 'tana/invalid';";
let error = format_validation_error(
code,
"test.ts",
"Invalid Import",
1,
26,
"Module 'tana/invalid' not found",
"Available modules: tana/core, tana/kv",
12,
);
assert!(error.contains("❌ Invalid Import"));
assert!(error.contains("test.ts:1:26"));
assert!(error.contains("tana/invalid"));
assert!(error.contains("^^^^^^^^^^^^")); assert!(error.contains("= help: Available modules"));
}
#[test]
fn test_multiline_code() {
let code = "line 1\nline 2 with error\nline 3";
let error = format_validation_error(
code,
"multi.ts",
"Type Error",
2,
7,
"Something wrong here",
"Fix it like this",
4,
);
assert!(error.contains("❌ Type Error"));
assert!(error.contains("multi.ts:2:7"));
assert!(error.contains("line 2 with error"));
assert!(error.contains("^^^^")); }
#[test]
fn test_underline_length_minimum() {
let error = format_validation_error(
"test",
"test.ts",
"Error",
1,
1,
"msg",
"help",
0, );
assert!(error.contains("^")); }
#[test]
fn test_out_of_bounds_line() {
let error = format_validation_error(
"only one line",
"test.ts",
"Error",
999,
1,
"msg",
"help",
5,
);
assert!(error.contains("❌ Error"));
assert!(error.contains("999 │")); }
}