...
This commit is contained in:
		
							
								
								
									
										32
									
								
								examples/loadscripts/scripts/math_utils.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								examples/loadscripts/scripts/math_utils.rhai
									
									
									
									
									
										Normal 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))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								examples/loadscripts/scripts/string_utils.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								examples/loadscripts/scripts/string_utils.rhai
									
									
									
									
									
										Normal 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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								examples/loadscripts/scripts/test_utils.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								examples/loadscripts/scripts/test_utils.rhai
									
									
									
									
									
										Normal 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								examples/loadscripts/test_dynamic_loading.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								examples/loadscripts/test_dynamic_loading.rs
									
									
									
									
									
										Normal 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(())
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user