use rhai::Engine; use rhai_wrapper::rust_rhai_wrapper; use std::error::Error; use std::fmt; // Define a custom error type for Result examples #[derive(Debug, Clone)] struct MyError(String); impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) } } impl Error for MyError {} impl From for MyError { fn from(s: String) -> Self { MyError(s) } } fn main() { // Create a Rhai engine let mut engine = Engine::new(); // 1. Basic example: Add two numbers // Define the original Rust function fn add(a: i32, b: i32) -> i32 { a + b } // Register it with Rhai engine.register_fn("add_rhai", add); // Create a wrapper function that calls Rhai which calls the Rust function rust_rhai_wrapper!(add_via_rhai, "add_rhai", (i32, i32) -> i32); // Test the full circle let result = add_via_rhai(&mut engine, 5, 3); println!("add_via_rhai(5, 3) = {}", result); // 2. String manipulation example fn concat(s1: String, s2: String) -> String { format!("{} {}", s1, s2) } engine.register_fn("concat_rhai", concat); rust_rhai_wrapper!(concat_via_rhai, "concat_rhai", (String, String) -> String); let result = concat_via_rhai(&mut engine, "Hello".to_string(), "World".to_string()); println!("concat_via_rhai(\"Hello\", \"World\") = {}", result); // 3. Function with no arguments fn get_random() -> i32 { 42 // Not so random, but it's just an example } engine.register_fn("get_random_rhai", get_random); rust_rhai_wrapper!(get_random_via_rhai, "get_random_rhai", () -> i32); let result = get_random_via_rhai(&mut engine); println!("get_random_via_rhai() = {}", result); // 4. Function with more arguments fn calculate(a: i32, b: i32, c: i32, d: i32) -> i32 { a + b * c - d } engine.register_fn("calculate_rhai", calculate); rust_rhai_wrapper!(calculate_via_rhai, "calculate_rhai", (i32, i32, i32, i32) -> i32); let result = calculate_via_rhai(&mut engine, 5, 3, 2, 1); println!("calculate_via_rhai(5, 3, 2, 1) = {}", result); // 5. Function that handles errors with a custom return type fn divide(a: i32, b: i32) -> Result { if b == 0 { Err("Division by zero".to_string()) } else { Ok(a / b) } } // Register a safe division function that returns an array with success flag and result/error engine.register_fn("safe_divide", |a: i32, b: i32| -> rhai::Array { if b == 0 { // Return [false, error message] let mut arr = rhai::Array::new(); arr.push(rhai::Dynamic::from(false)); arr.push(rhai::Dynamic::from("Division by zero")); arr } else { // Return [true, result] let mut arr = rhai::Array::new(); arr.push(rhai::Dynamic::from(true)); arr.push(rhai::Dynamic::from(a / b)); arr } }); // Create a wrapper for the safe_divide function rust_rhai_wrapper!(safe_divide_via_rhai, "safe_divide", (i32, i32) -> rhai::Array); // Test success case let result = safe_divide_via_rhai(&mut engine, 10, 2); println!("safe_divide_via_rhai(10, 2) = {:?}", result); // Test error case let result = safe_divide_via_rhai(&mut engine, 10, 0); println!("safe_divide_via_rhai(10, 0) = {:?}", result); // Process the result let success = result[0].as_bool().unwrap(); if success { println!("Division result: {}", result[1].as_int().unwrap()); } else { println!("Division error: {}", result[1].clone().into_string().unwrap()); } // 6. Complex example: Using a custom type with Rhai #[derive(Debug, Clone)] struct Person { name: String, age: i32, } // Register type and methods with Rhai engine.register_type::(); engine.register_fn("new_person", |name: String, age: i32| -> Person { Person { name, age } }); engine.register_fn("get_name", |p: &mut Person| -> String { p.name.clone() }); engine.register_fn("get_age", |p: &mut Person| -> i32 { p.age }); engine.register_fn("is_adult", |p: &mut Person| -> bool { p.age >= 18 }); // Register a function that creates a person and checks if they're an adult engine.register_fn("create_and_check_person", |name: String, age: i32| -> rhai::Array { let person = Person { name, age }; let is_adult = person.age >= 18; // Create an array with the person and the is_adult flag let mut arr = rhai::Array::new(); // Convert the person to a map for Rhai let mut map = rhai::Map::new(); map.insert("name".into(), rhai::Dynamic::from(person.name)); map.insert("age".into(), rhai::Dynamic::from(person.age)); arr.push(rhai::Dynamic::from(map)); arr.push(rhai::Dynamic::from(is_adult)); arr }); // Create a wrapper for the Rhai function rust_rhai_wrapper!(create_person_via_rhai, "create_and_check_person", (String, i32) -> rhai::Array); // Test the wrapper let result = create_person_via_rhai(&mut engine, "Alice".to_string(), 25); println!("create_person_via_rhai(\"Alice\", 25) = {:?}", result); // Extract data from the Rhai array let person_map = result[0].clone().try_cast::().expect("Expected a Map"); let is_adult = result[1].clone().as_bool().expect("Expected a boolean"); println!("Person: {:?}, Is Adult: {}", person_map, is_adult); println!("All examples completed successfully!"); }