Compare commits
11 Commits
developmen
...
main
Author | SHA1 | Date | |
---|---|---|---|
f409246ed3 | |||
1157d6da64 | |||
6389da0372 | |||
3b4db8b66b | |||
a361f6d4ba | |||
4b1f305b07 | |||
452150a2fc | |||
d3c5f97469 | |||
e16d4270c0 | |||
868c870bf0 | |||
a9a44f96cf |
@ -1,3 +1,6 @@
|
|||||||
# rhaj
|
# rhaj
|
||||||
|
|
||||||
DSL's for our ecosystem
|
```bash
|
||||||
|
#tests, following one shows how we can dynamically load the functions from a set of rhai scripts
|
||||||
|
cargo run --bin test_dynamic_loading
|
||||||
|
```
|
@ -1,6 +0,0 @@
|
|||||||
//! Rhai Engine Library
|
|
||||||
//!
|
|
||||||
//! This library provides utilities for working with Rhai scripts.
|
|
||||||
|
|
||||||
// Simple example of exposing Rhai functions to a hashmap
|
|
||||||
pub mod simple_example;
|
|
@ -11,6 +11,10 @@ path = "src/lib.rs"
|
|||||||
name = "rhai_engine"
|
name = "rhai_engine"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "test_dynamic_loading"
|
||||||
|
path = "examples/loadscripts/test_dynamic_loading.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rhai = "1.12.0"
|
rhai = "1.12.0"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
@ -1,4 +1,4 @@
|
|||||||
// Math utility functions for Terra templates
|
// Math utility functions for Tera templates
|
||||||
|
|
||||||
// Format a number with commas as thousands separators
|
// Format a number with commas as thousands separators
|
||||||
fn format_number(num) {
|
fn format_number(num) {
|
@ -1,4 +1,4 @@
|
|||||||
// String manipulation functions that will be exposed to Terra templates
|
// String manipulation functions that will be exposed to Tera templates
|
||||||
|
|
||||||
// Capitalize the first letter of each word
|
// Capitalize the first letter of each word
|
||||||
fn capitalize(text) {
|
fn capitalize(text) {
|
98
rhai_engine/examples/loadscripts/test_dynamic_loading.rs
Normal file
98
rhai_engine/examples/loadscripts/test_dynamic_loading.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use rhai::Dynamic;
|
||||||
|
use rhai_engine::ScriptManager;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
/// Test the dynamic loading of Rhai scripts and functions
|
||||||
|
pub fn main() -> Result<(), String> {
|
||||||
|
println!("\n=== TESTING DYNAMIC FUNCTION LOADING ===\n");
|
||||||
|
|
||||||
|
// Create a new ScriptManager
|
||||||
|
let mut script_manager = ScriptManager::new();
|
||||||
|
|
||||||
|
println!("Loading Rhai scripts from scripts directory...");
|
||||||
|
|
||||||
|
// Get the scripts directory path
|
||||||
|
let scripts_dir = Path::new("examples/loadscripts/scripts");
|
||||||
|
|
||||||
|
// Use the ScriptManager to load all scripts from the directory
|
||||||
|
let loaded_scripts = script_manager.load_scripts_from_directory(scripts_dir)?;
|
||||||
|
|
||||||
|
// Print loaded scripts
|
||||||
|
println!("\nLoaded scripts:");
|
||||||
|
for script in &loaded_scripts {
|
||||||
|
println!(" - {}", script);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all available functions using the get_function_names method
|
||||||
|
let function_names = script_manager.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:");
|
||||||
|
|
||||||
|
//TODO: should not start with string_utils we want capitalize as function usable as is
|
||||||
|
script_manager.run( "string_utils:capitalize(hello world);")?;
|
||||||
|
script_manager.run( "math_utils:format_number(1234567);")?;
|
||||||
|
|
||||||
|
|
||||||
|
// Test evaluating a complex script
|
||||||
|
println!("\nEvaluating a complex script:");
|
||||||
|
let complex_script = r#"
|
||||||
|
let sentence = "Count the words in this sentence";
|
||||||
|
let count = test_utils:count_words(sentence);
|
||||||
|
print("Word count: " + truncate("count",1));
|
||||||
|
count * 2 // Return double the word count
|
||||||
|
"#;
|
||||||
|
|
||||||
|
// Evaluate the script
|
||||||
|
println!("```\n{}\n```", complex_script);
|
||||||
|
match script_manager.eval::<Dynamic>(complex_script) {
|
||||||
|
Ok(result) => println!(" Result: {}", result),
|
||||||
|
Err(e) => println!(" Error: {}", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
# Product Catalog
|
||||||
|
|
||||||
|
{% let products = get_products() %}
|
||||||
|
|
||||||
|
## All Products
|
||||||
|
|
||||||
|
{% for product in products %}
|
||||||
|
### {{ product.name }}
|
||||||
|
|
||||||
|
**Price:** {{ format_price(product.price) }}
|
||||||
|
|
||||||
|
#### Features:
|
||||||
|
{% for feature in product.features %}
|
||||||
|
- {{ feature }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
*Status: {% if product.available %}✅ In Stock{% else %}❌ Out of Stock{% endif %}*
|
||||||
|
|
||||||
|
---
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
## Available Products
|
||||||
|
|
||||||
|
{% let available_products = get_available_products() %}
|
||||||
|
*Available Products: {{ available_products.len() }}*
|
||||||
|
|
||||||
|
{% for product in available_products %}
|
||||||
|
### {{ product.name }}
|
||||||
|
|
||||||
|
**Price:** {{ format_price(product.price) }}
|
||||||
|
|
||||||
|
---
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
## Total Catalog Value
|
||||||
|
|
||||||
|
**Total Value:** {{ format_price(calculate_total_price()) }}
|
||||||
|
|
||||||
|
## User Information
|
||||||
|
|
||||||
|
{% let user = get_user() %}
|
||||||
|
|
||||||
|
**Name:** {{ user.name }}
|
||||||
|
**Email:** {{ user.email }}
|
||||||
|
**Role:** {{ user.role }}
|
||||||
|
**Theme:** {{ user.settings.theme }}
|
||||||
|
|
||||||
|
### Order History
|
||||||
|
|
||||||
|
{% for order in user.orders %}
|
||||||
|
- **{{ order.id }}** ({{ order.date }}) - {{ format_price(order.total) }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
## All Product Features
|
||||||
|
|
||||||
|
{% let features = get_all_features() %}
|
||||||
|
{% for feature in features %}
|
||||||
|
- {{ feature }}
|
||||||
|
{% endfor %}
|
2
rhai_engine/examples/simple/producttemplates/readme.md
Normal file
2
rhai_engine/examples/simple/producttemplates/readme.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
the data objects which need to be filled into product_catalog.tera come from ../scripts/
|
||||||
|
|
@ -0,0 +1,146 @@
|
|||||||
|
// Data objects for Tera template integration
|
||||||
|
// This script defines complex objects that can be accessed from Tera templates
|
||||||
|
|
||||||
|
// Create a products catalog object
|
||||||
|
fn create_products() {
|
||||||
|
let products = [
|
||||||
|
#{
|
||||||
|
id: 1,
|
||||||
|
name: "Laptop",
|
||||||
|
price: 1299.99,
|
||||||
|
features: [
|
||||||
|
"16GB RAM",
|
||||||
|
"512GB SSD",
|
||||||
|
"Intel i7 processor"
|
||||||
|
],
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
#{
|
||||||
|
id: 2,
|
||||||
|
name: "Smartphone",
|
||||||
|
price: 899.99,
|
||||||
|
features: [
|
||||||
|
"6.7 inch display",
|
||||||
|
"128GB storage",
|
||||||
|
"12MP camera"
|
||||||
|
],
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
#{
|
||||||
|
id: 3,
|
||||||
|
name: "Tablet",
|
||||||
|
price: 499.99,
|
||||||
|
features: [
|
||||||
|
"10.9 inch display",
|
||||||
|
"64GB storage",
|
||||||
|
"A14 chip"
|
||||||
|
],
|
||||||
|
available: false
|
||||||
|
},
|
||||||
|
#{
|
||||||
|
id: 4,
|
||||||
|
name: "Headphones",
|
||||||
|
price: 249.99,
|
||||||
|
features: [
|
||||||
|
"Noise cancellation",
|
||||||
|
"Wireless",
|
||||||
|
"20h battery life"
|
||||||
|
],
|
||||||
|
available: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
products
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all products
|
||||||
|
fn get_products() {
|
||||||
|
create_products()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get available products only
|
||||||
|
fn get_available_products() {
|
||||||
|
let all_products = create_products();
|
||||||
|
let available = [];
|
||||||
|
|
||||||
|
for product in all_products {
|
||||||
|
if product.available {
|
||||||
|
available.push(product);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
available
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a specific product by ID
|
||||||
|
fn get_product_by_id(id) {
|
||||||
|
let products = create_products();
|
||||||
|
|
||||||
|
// Convert ID to integer to ensure type compatibility
|
||||||
|
let search_id = id.to_int();
|
||||||
|
|
||||||
|
for product in products {
|
||||||
|
if product.id == search_id {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#{} // Return empty object if not found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate total price of all products
|
||||||
|
fn calculate_total_price() {
|
||||||
|
let products = create_products();
|
||||||
|
let total = 0.0;
|
||||||
|
|
||||||
|
for product in products {
|
||||||
|
total += product.price;
|
||||||
|
}
|
||||||
|
|
||||||
|
total
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format price with currency symbol
|
||||||
|
fn format_price(price) {
|
||||||
|
"$" + price.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all product features as a flattened array
|
||||||
|
fn get_all_features() {
|
||||||
|
let products = create_products();
|
||||||
|
let all_features = [];
|
||||||
|
|
||||||
|
for product in products {
|
||||||
|
for feature in product.features {
|
||||||
|
all_features.push(feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
all_features
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a user object
|
||||||
|
fn get_user() {
|
||||||
|
#{
|
||||||
|
name: "John Doe",
|
||||||
|
email: "john@example.com",
|
||||||
|
role: "admin",
|
||||||
|
settings: #{
|
||||||
|
theme: "dark",
|
||||||
|
notifications: true,
|
||||||
|
language: "en"
|
||||||
|
},
|
||||||
|
orders: [
|
||||||
|
#{
|
||||||
|
id: "ORD-001",
|
||||||
|
date: "2025-03-25",
|
||||||
|
total: 1299.99
|
||||||
|
},
|
||||||
|
#{
|
||||||
|
id: "ORD-002",
|
||||||
|
date: "2025-04-01",
|
||||||
|
total: 249.99
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user