more efforts to automate rhai bindings
This commit is contained in:
176
rhai_wrapper/examples/rust_rhai_wrapper_example.rs
Normal file
176
rhai_wrapper/examples/rust_rhai_wrapper_example.rs
Normal file
@@ -0,0 +1,176 @@
|
||||
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<String> 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<i32, String> {
|
||||
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::<Person>();
|
||||
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::<rhai::Map>().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!");
|
||||
}
|
Reference in New Issue
Block a user