This commit is contained in:
2025-04-03 12:31:01 +02:00
parent 868c870bf0
commit e16d4270c0
9 changed files with 61 additions and 114 deletions

View File

@@ -0,0 +1,32 @@
// Math utility functions for Tera templates
// Format a number with commas as thousands separators
fn format_number(num) {
let str = num.to_string();
let result = "";
let len = str.len;
for i in 0..len {
if i > 0 && (len - i) % 3 == 0 {
result += ",";
}
result += str.substr(i, 1);
}
result
}
// Calculate percentage
fn percentage(value, total) {
if total == 0 {
return "0%";
}
let pct = (value / total) * 100.0;
pct.round().to_string() + "%"
}
// Format currency
fn currency(amount, symbol) {
symbol + format_number(amount.round(2))
}

View File

@@ -0,0 +1,43 @@
// String manipulation functions that will be exposed to Tera templates
// Capitalize the first letter of each word
fn capitalize(text) {
if text.len == 0 {
return "";
}
let words = text.split(" ");
let result = [];
for word in words {
if word.len > 0 {
let first_char = word.substr(0, 1).to_upper();
let rest = word.substr(1, word.len - 1);
result.push(first_char + rest);
} else {
result.push("");
}
}
result.join(" ")
}
// Truncate text with ellipsis
fn truncate(text, max_length) {
if text.len <= max_length {
return text;
}
text.substr(0, max_length - 3) + "..."
}
// Convert text to slug format (lowercase, hyphens)
fn slugify(text) {
let slug = text.to_lower();
slug = slug.replace(" ", "-");
slug = slug.replace(".", "");
slug = slug.replace(",", "");
slug = slug.replace("!", "");
slug = slug.replace("?", "");
slug
}

View File

@@ -0,0 +1,56 @@
// Test utility functions to verify dynamic function discovery
// These functions were not in the original hardcoded lists
// Reverse a string
fn reverse_string(text) {
let result = "";
let i = text.len - 1;
// Using a different approach to reverse the string
// We'll iterate backwards with a while loop instead of using step
while i >= 0 {
result += text.substr(i, 1);
i -= 1;
}
result
}
// Count words in a string - rewritten to avoid split issues
fn count_words(text) {
if text.len == 0 {
return 0;
}
// Manual word counting implementation
let count = 1; // Start with 1 for the first word
let in_word = true;
for i in 0..text.len {
let char = text.substr(i, 1);
if char == " " {
in_word = false;
} else if !in_word {
// Found a non-space after a space = new word
count += 1;
in_word = true;
}
}
if text.substr(0, 1) == " " {
// If text starts with space, reduce count
count -= 1;
}
count
}
// Calculate factorial
fn factorial(n) {
// Ensure consistent integer type using to_int()
let num = n.to_int();
if num <= 1 {
return 1;
}
num * factorial(num-1)
}

View File

@@ -0,0 +1,93 @@
use crate::tera_integration::RhaiTeraIntegration;
use std::collections::HashMap;
use rhai::Dynamic;
/// Test the dynamic loading of Rhai scripts and functions
pub fn test_dynamic_loading() -> Result<(), String> {
println!("\n=== TESTING DYNAMIC FUNCTION LOADING ===\n");
// Create a new RhaiTeraIntegration
let mut integration = RhaiTeraIntegration::new();
println!("Loading Rhai scripts...");
// Load the original scripts
integration.load_script("string_utils", "src/tera_integration/scripts/string_utils.rhai")?;
integration.load_script("math_utils", "src/tera_integration/scripts/math_utils.rhai")?;
// Load the new test script (which wasn't in the original hardcoded lists)
integration.load_script("test_utils", "src/tera_integration/scripts/test_utils.rhai")?;
// Get function names
let function_names = integration.get_function_names();
// Print all available functions
println!("\nAll available functions:");
for name in &function_names {
println!(" - {}", name);
}
// Group functions by their script prefix to display nicely
let scripts = group_functions_by_script(&function_names);
// Display functions by script
display_functions_by_script(&scripts);
// Test some functions from each script
println!("\nDynamic function testing:");
// Test original string utils functions
test_function(&integration, "string_utils:capitalize", vec![Dynamic::from("hello world")])?;
// Test original math utils functions
test_function(&integration, "math_utils:format_number", vec![Dynamic::from(1234567)])?;
// Test new functions from test_utils
test_function(&integration, "test_utils:reverse_string", vec![Dynamic::from("hello world")])?;
test_function(&integration, "test_utils:count_words",
vec![Dynamic::from("this is a test sentence")])?;
test_function(&integration, "test_utils:factorial",
vec![Dynamic::from(5)])?;
println!("\n=== DYNAMIC FUNCTION LOADING TEST COMPLETE ===\n");
Ok(())
}
// Helper function to group functions by script
fn group_functions_by_script(function_names: &[String]) -> HashMap<String, Vec<String>> {
let mut scripts = HashMap::new();
for name in function_names {
let parts: Vec<&str> = name.split(':').collect();
if parts.len() == 2 {
let script = parts[0].to_string();
let func = parts[1].to_string();
scripts.entry(script).or_insert_with(Vec::new).push(func);
}
}
scripts
}
// Helper function to display functions grouped by script
fn display_functions_by_script(scripts: &HashMap<String, Vec<String>>) {
println!("\nFunctions by script:");
for (script, funcs) in scripts {
println!(" {}:", script);
for func in funcs {
println!(" - {}", func);
}
}
}
// Helper function to test a function and display its result
fn test_function(integration: &RhaiTeraIntegration, name: &str, args: Vec<Dynamic>) -> Result<(), String> {
let result = integration.call_function(name, args)?;
println!(" {}() => {}", name, result);
Ok(())
}