more efforts to automate rhai bindings
This commit is contained in:
@@ -208,3 +208,601 @@ macro_rules! wrap_for_rhai {
|
||||
$func
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro to wrap a Rust function that returns Option<T> for Rhai.
|
||||
/// It converts Some(T) to Dynamic::from(T) and None to Dynamic::UNIT.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_option_return {
|
||||
// Matches fn_name(arg1_type, arg2_type) -> Option<ReturnType>
|
||||
// Example: get_user_by_id(OurDB, INT) -> Option<User>
|
||||
// Macro call: wrap_option_return!(get_user_by_id, OurDB, INT => User)
|
||||
// Generated closure: |db: OurDB, id: INT| -> rhai::Dynamic { ... }
|
||||
($func:ident, $Arg1Type:ty, $Arg2Type:ty => $ReturnType:ident) => {
|
||||
|arg1: $Arg1Type, arg2: $Arg2Type| -> rhai::Dynamic {
|
||||
match $func(arg1, arg2) {
|
||||
Some(value) => {
|
||||
// Ensure the value is converted into a Dynamic.
|
||||
// If $ReturnType is already a CustomType, this should work directly.
|
||||
rhai::Dynamic::from(value)
|
||||
}
|
||||
None => rhai::Dynamic::UNIT,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add more arms here if functions with different numbers/types of arguments returning Option<T>
|
||||
// are needed.
|
||||
// For example, for a function with one argument:
|
||||
// ($func:ident, $Arg1Type:ty => $ReturnType:ident) => { ... };
|
||||
}
|
||||
|
||||
/// Macro to wrap a Rust function that returns Vec<T> for Rhai.
|
||||
/// It converts the Vec into a rhai::Array.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_vec_return {
|
||||
// For functions like fn(Arg1) -> Vec<InnerType>
|
||||
// Example: get_all_users(db: OurDB) -> Vec<User>
|
||||
// Macro call: wrap_vec_return!(get_all_users, OurDB => User)
|
||||
// Generated closure: |db: OurDB| -> rhai::Array { ... }
|
||||
($func:ident, $Arg1Type:ty => $InnerVecType:ty) => {
|
||||
|arg1_val: $Arg1Type| -> rhai::Array {
|
||||
let result_vec: std::vec::Vec<$InnerVecType> = $func(arg1_val);
|
||||
result_vec.into_iter().map(rhai::Dynamic::from).collect::<rhai::Array>()
|
||||
}
|
||||
};
|
||||
|
||||
// For functions like fn(Arg1, Arg2) -> Vec<InnerType>
|
||||
($func:ident, $Arg1Type:ty, $Arg2Type:ty => $InnerVecType:ty) => {
|
||||
|arg1_val: $Arg1Type, arg2_val: $Arg2Type| -> rhai::Array {
|
||||
let result_vec: std::vec::Vec<$InnerVecType> = $func(arg1_val, arg2_val);
|
||||
result_vec.into_iter().map(rhai::Dynamic::from).collect::<rhai::Array>()
|
||||
}
|
||||
};
|
||||
|
||||
// For functions like fn() -> Vec<InnerType>
|
||||
($func:ident, () => $InnerVecType:ty) => {
|
||||
|| -> rhai::Array {
|
||||
let result_vec: std::vec::Vec<$InnerVecType> = $func();
|
||||
result_vec.into_iter().map(rhai::Dynamic::from).collect::<rhai::Array>()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! wrap_option_vec_return {
|
||||
// Case: fn_name(Arg1Type, Arg2Type) -> Option<Vec<InnerType>>
|
||||
// Generates a closure: |arg1_val: Arg1Type, arg2_val: Arg2Type| -> rhai::Dynamic
|
||||
($func:ident, $Arg1Type:ty, $Arg2Type:ty => $InnerVecType:ty) => {
|
||||
move |arg1_val: $Arg1Type, arg2_val: $Arg2Type| -> rhai::Dynamic {
|
||||
match $func(arg1_val, arg2_val) { // Call the original Rust function
|
||||
Some(vec_inner) => { // vec_inner is Vec<$InnerVecType>
|
||||
let rhai_array = vec_inner.into_iter()
|
||||
.map(rhai::Dynamic::from) // Each $InnerVecType must be convertible to Dynamic
|
||||
.collect::<rhai::Array>();
|
||||
rhai::Dynamic::from(rhai_array)
|
||||
}
|
||||
None => rhai::Dynamic::UNIT,
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO: Add arms for different numbers of arguments if needed, e.g.:
|
||||
// ($func:ident, $Arg1Type:ty => $InnerVecType:ty) => { ... }
|
||||
// ($func:ident => $InnerVecType:ty) => { ... }
|
||||
}
|
||||
|
||||
/// Wraps a Rust function that returns `Result<Option<T>, ErrorType>` for Rhai.
|
||||
/// The generated closure returns `Result<rhai::Dynamic, Box<rhai::EvalAltResult>>`.
|
||||
/// Assumes `T` implements a `to_rhai_map(&self) -> rhai::Map` method.
|
||||
/// Assumes `ErrorType` implements `std::fmt::Display`.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_option_return_result {
|
||||
// Case: Function with DB connection and 1 additional argument
|
||||
(
|
||||
$func:path, // Path to the actual Rust function
|
||||
$DbConnType:ty, $Arg1Type:ty => $ReturnType:ty, // DB conn type, Arg types for actual func
|
||||
$ErrorType:ty // Error type from actual func
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType, arg1_val: $Arg1Type|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match $func(db_conn_instance, arg1_val) { // Call the actual function
|
||||
Ok(Some(value)) => {
|
||||
// Assumes ReturnType has a .to_rhai_map() method.
|
||||
Ok(rhai::Dynamic::from(value.to_rhai_map()))
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(), // Requires ErrorType: Display
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Case: Function with DB connection and 0 additional arguments
|
||||
(
|
||||
$func:path,
|
||||
$DbConnType:ty => $ReturnType:ty,
|
||||
$ErrorType:ty
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match $func(db_conn_instance) { // Call the actual function
|
||||
Ok(Some(value)) => {
|
||||
Ok(rhai::Dynamic::from(value.to_rhai_map()))
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(),
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO: Add variants for more arguments as needed
|
||||
}
|
||||
|
||||
/// Wraps a Rust function that returns `Result<Vec<T>, ErrorType>` for Rhai.
|
||||
/// The generated closure returns `Result<rhai::Dynamic, Box<rhai::EvalAltResult>>`.
|
||||
/// Assumes `T` implements a `to_rhai_map(&self) -> rhai::Map` method.
|
||||
/// Assumes `ErrorType` implements `std::fmt::Display`.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_vec_return_result {
|
||||
// Case: Function with DB connection and 1 additional argument
|
||||
(
|
||||
$func:path, // Path to the actual Rust function
|
||||
$DbConnType:ty, $Arg1Type:ty => $ReturnType:ty, // DB conn type, Arg types for actual func
|
||||
$ErrorType:ty // Error type from actual func
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType, arg1_val: $Arg1Type|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match $func(db_conn_instance, arg1_val) { // Call the actual function
|
||||
Ok(vec_of_values) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.to_rhai_map()))
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(), // Requires ErrorType: Display
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Case: Function with DB connection and 0 additional arguments (e.g., get_all)
|
||||
(
|
||||
$func:path,
|
||||
$DbConnType:ty => $ReturnType:ty,
|
||||
$ErrorType:ty
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match $func(db_conn_instance) { // Call the actual function
|
||||
Ok(vec_of_values) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.to_rhai_map()))
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(),
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO: Add variants for more arguments as needed
|
||||
}
|
||||
|
||||
/// Wraps a Rust function that returns `Result<Option<Vec<T>>, ErrorType>` for Rhai.
|
||||
/// The generated closure returns `Result<rhai::Dynamic, Box<rhai::EvalAltResult>>`.
|
||||
/// Assumes `T` implements a `to_rhai_map(&self) -> rhai::Map` method.
|
||||
/// Assumes `ErrorType` implements `std::fmt::Display`.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_option_vec_return_result {
|
||||
// Case: Function with DB connection and 1 additional argument
|
||||
(
|
||||
$func:path, // Path to the actual Rust function
|
||||
$DbConnType:ty, $Arg1Type:ty => $ReturnType:ty, // DB conn type, Arg types for actual func
|
||||
$ErrorType:ty // Error type from actual func
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType, arg1_val: $Arg1Type|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match $func(db_conn_instance, arg1_val) { // Call the actual function
|
||||
Ok(Some(vec_of_values)) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.to_rhai_map()))
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(), // Requires ErrorType: Display
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Case: Function with DB connection and 0 additional arguments
|
||||
(
|
||||
$func:path,
|
||||
$DbConnType:ty => $ReturnType:ty,
|
||||
$ErrorType:ty
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match $func(db_conn_instance) { // Call the actual function
|
||||
Ok(Some(vec_of_values)) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.to_rhai_map()))
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(),
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO: Add variants for more arguments as needed
|
||||
}
|
||||
|
||||
// --- Macros for methods returning Result<_, _> for fallible operations --- //
|
||||
|
||||
/// Wraps a Rust method that returns `Result<Option<T>, ErrorType>` for Rhai.
|
||||
/// The generated closure returns `Result<rhai::Dynamic, Box<rhai::EvalAltResult>>`.
|
||||
/// Assumes `T` implements `Clone` and is Rhai `CustomType`.
|
||||
/// Assumes `ErrorType` implements `std::fmt::Display`.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_option_method_result {
|
||||
// Case: Method with DB connection (self) and 1 additional argument
|
||||
(
|
||||
$method_name:ident, // Name of the method on the Collection
|
||||
$DbConnType:ty, $Arg1Type:ty => $ReturnType:ty, // DB conn type (e.g. &Collection), Arg types
|
||||
$ErrorType:ty // Error type from method
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType, arg1_val: $Arg1Type|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match db_conn_instance.$method_name(arg1_val) { // Call the method
|
||||
Ok(Some(value)) => {
|
||||
Ok(rhai::Dynamic::from(value.clone())) // Assumes ReturnType: Clone
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(), // ErrorType: Display
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Case: Method with DB connection (self) and 0 additional arguments
|
||||
(
|
||||
$method_name:ident,
|
||||
$DbConnType:ty => $ReturnType:ty,
|
||||
$ErrorType:ty
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match db_conn_instance.$method_name() { // Call the method
|
||||
Ok(Some(value)) => {
|
||||
Ok(rhai::Dynamic::from(value.clone())) // Assumes ReturnType: Clone
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(),
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO: Add variants for more arguments as needed
|
||||
}
|
||||
|
||||
/// Wraps a Rust method that returns `Result<Vec<T>, ErrorType>` for Rhai.
|
||||
/// The generated closure returns `Result<rhai::Dynamic, Box<rhai::EvalAltResult>>`.
|
||||
/// Assumes `T` implements `Clone` and is Rhai `CustomType`.
|
||||
/// Assumes `ErrorType` implements `std::fmt::Display`.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_vec_method_result {
|
||||
// Case: Method with DB connection (self) and 1 additional argument
|
||||
(
|
||||
$method_name:ident, // Name of the method on the Collection
|
||||
$DbConnType:ty, $Arg1Type:ty => $ReturnType:ty, // DB conn type, Arg types
|
||||
$ErrorType:ty // Error type from method
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType, arg1_val: $Arg1Type|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match db_conn_instance.$method_name(arg1_val) { // Call the method
|
||||
Ok(vec_of_values) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.clone())) // Assumes ReturnType: Clone
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(), // ErrorType: Display
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Case: Method with DB connection (self) and 0 additional arguments (e.g., get_all)
|
||||
(
|
||||
$method_name:ident,
|
||||
$DbConnType:ty => $ReturnType:ty,
|
||||
$ErrorType:ty
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match db_conn_instance.$method_name() { // Call the method
|
||||
Ok(vec_of_values) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.clone())) // Assumes ReturnType: Clone
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(),
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO: Add variants for more arguments as needed
|
||||
}
|
||||
|
||||
/// Wraps a Rust method that returns `Result<Option<Vec<T>>, ErrorType>` for Rhai.
|
||||
/// The generated closure returns `Result<rhai::Dynamic, Box<rhai::EvalAltResult>>`.
|
||||
/// Assumes `T` implements `Clone` and is Rhai `CustomType`.
|
||||
/// Assumes `ErrorType` implements `std::fmt::Display`.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_option_vec_method_result {
|
||||
// Case: Method with DB connection (self) and 1 additional argument
|
||||
(
|
||||
$method_name:ident, // Name of the method on the Collection
|
||||
$DbConnType:ty, $Arg1Type:ty => $ReturnType:ty, // DB conn type, Arg types
|
||||
$ErrorType:ty // Error type from method
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType, arg1_val: $Arg1Type|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match db_conn_instance.$method_name(arg1_val) { // Call the method
|
||||
Ok(Some(vec_of_values)) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.clone())) // Assumes ReturnType: Clone
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(), // ErrorType: Display
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Case: Method with DB connection (self) and 0 additional arguments
|
||||
(
|
||||
$method_name:ident,
|
||||
$DbConnType:ty => $ReturnType:ty,
|
||||
$ErrorType:ty
|
||||
) => {
|
||||
move |db_conn_instance: $DbConnType|
|
||||
-> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||
match db_conn_instance.$method_name() { // Call the method
|
||||
Ok(Some(vec_of_values)) => {
|
||||
let rhai_array = vec_of_values
|
||||
.into_iter()
|
||||
.map(|value| rhai::Dynamic::from(value.clone())) // Assumes ReturnType: Clone
|
||||
.collect::<rhai::Array>();
|
||||
Ok(rhai::Dynamic::from(rhai_array))
|
||||
}
|
||||
Ok(None) => Ok(rhai::Dynamic::UNIT),
|
||||
Err(err) => {
|
||||
Err(Box::new(rhai::EvalAltResult::ErrorRuntime(
|
||||
format!("Function Error: {}", err).into(),
|
||||
rhai::Position::NONE,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO: Add variants for more arguments as needed
|
||||
}
|
||||
|
||||
// TODO: Consider merging wrap_option_return, wrap_vec_return, and wrap_option_vec_return
|
||||
// into a more general wrap_for_rhai! macro if patterns become too numerous or complex.
|
||||
// For now, separate macros are clear for distinct return type patterns.
|
||||
|
||||
/// A macro that creates a Rust function that calls a Rhai engine to execute a Rhai function which wraps an underlying Rust function.
|
||||
/// This creates a full circle of Rust → Rhai → Rust function calls.
|
||||
///
|
||||
/// # Example Usage
|
||||
/// ```rust,ignore
|
||||
/// // Define a Rust function
|
||||
/// fn add(a: i32, b: i32) -> i32 {
|
||||
/// a + b
|
||||
/// }
|
||||
///
|
||||
/// // Register it with Rhai (assuming engine is already created)
|
||||
/// engine.register_fn("add_rhai", add);
|
||||
///
|
||||
/// // Create a wrapper function that takes an engine reference and calls the Rhai function
|
||||
/// rust_rhai_wrapper!(add_via_rhai, "add_rhai", (i32, i32) -> i32);
|
||||
///
|
||||
/// // Now you can call add_via_rhai which will call the Rhai function add_rhai which calls the Rust function add
|
||||
/// let result = add_via_rhai(&mut engine, 5, 3); // result = 8
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! rust_rhai_wrapper {
|
||||
// Basic case: function with no arguments
|
||||
($func_name:ident, $rhai_func_name:expr, () -> $return_type:ty) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine) -> $return_type {
|
||||
let result = engine.eval::<$return_type>(
|
||||
&format!("{}()", $rhai_func_name)
|
||||
).expect(&format!("Failed to call Rhai function {}", $rhai_func_name));
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
// Function with one argument
|
||||
($func_name:ident, $rhai_func_name:expr, ($arg1_type:ty) -> $return_type:ty) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine, arg1: $arg1_type) -> $return_type {
|
||||
// Create a scope to pass arguments
|
||||
let mut scope = rhai::Scope::new();
|
||||
scope.push("arg1", arg1);
|
||||
|
||||
let result = engine.eval_with_scope::<$return_type>(
|
||||
&mut scope,
|
||||
&format!("{}(arg1)", $rhai_func_name)
|
||||
).expect(&format!("Failed to call Rhai function {}", $rhai_func_name));
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
// Function with two arguments
|
||||
($func_name:ident, $rhai_func_name:expr, ($arg1_type:ty, $arg2_type:ty) -> $return_type:ty) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine, arg1: $arg1_type, arg2: $arg2_type) -> $return_type {
|
||||
// Create a scope to pass arguments
|
||||
let mut scope = rhai::Scope::new();
|
||||
scope.push("arg1", arg1);
|
||||
scope.push("arg2", arg2);
|
||||
|
||||
let result = engine.eval_with_scope::<$return_type>(
|
||||
&mut scope,
|
||||
&format!("{}(arg1, arg2)", $rhai_func_name)
|
||||
).expect(&format!("Failed to call Rhai function {}", $rhai_func_name));
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
// Function with three arguments
|
||||
($func_name:ident, $rhai_func_name:expr, ($arg1_type:ty, $arg2_type:ty, $arg3_type:ty) -> $return_type:ty) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine, arg1: $arg1_type, arg2: $arg2_type, arg3: $arg3_type) -> $return_type {
|
||||
// Create a scope to pass arguments
|
||||
let mut scope = rhai::Scope::new();
|
||||
scope.push("arg1", arg1);
|
||||
scope.push("arg2", arg2);
|
||||
scope.push("arg3", arg3);
|
||||
|
||||
let result = engine.eval_with_scope::<$return_type>(
|
||||
&mut scope,
|
||||
&format!("{}(arg1, arg2, arg3)", $rhai_func_name)
|
||||
).expect(&format!("Failed to call Rhai function {}", $rhai_func_name));
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
// Function with four arguments
|
||||
($func_name:ident, $rhai_func_name:expr, ($arg1_type:ty, $arg2_type:ty, $arg3_type:ty, $arg4_type:ty) -> $return_type:ty) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine, arg1: $arg1_type, arg2: $arg2_type, arg3: $arg3_type, arg4: $arg4_type) -> $return_type {
|
||||
// Create a scope to pass arguments
|
||||
let mut scope = rhai::Scope::new();
|
||||
scope.push("arg1", arg1);
|
||||
scope.push("arg2", arg2);
|
||||
scope.push("arg3", arg3);
|
||||
scope.push("arg4", arg4);
|
||||
|
||||
let result = engine.eval_with_scope::<$return_type>(
|
||||
&mut scope,
|
||||
&format!("{}(arg1, arg2, arg3, arg4)", $rhai_func_name)
|
||||
).expect(&format!("Failed to call Rhai function {}", $rhai_func_name));
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
// Function with five arguments
|
||||
($func_name:ident, $rhai_func_name:expr, ($arg1_type:ty, $arg2_type:ty, $arg3_type:ty, $arg4_type:ty, $arg5_type:ty) -> $return_type:ty) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine, arg1: $arg1_type, arg2: $arg2_type, arg3: $arg3_type, arg4: $arg4_type, arg5: $arg5_type) -> $return_type {
|
||||
// Create a scope to pass arguments
|
||||
let mut scope = rhai::Scope::new();
|
||||
scope.push("arg1", arg1);
|
||||
scope.push("arg2", arg2);
|
||||
scope.push("arg3", arg3);
|
||||
scope.push("arg4", arg4);
|
||||
scope.push("arg5", arg5);
|
||||
|
||||
let result = engine.eval_with_scope::<$return_type>(
|
||||
&mut scope,
|
||||
&format!("{}(arg1, arg2, arg3, arg4, arg5)", $rhai_func_name)
|
||||
).expect(&format!("Failed to call Rhai function {}", $rhai_func_name));
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
// Function with a Result return type and no arguments
|
||||
($func_name:ident, $rhai_func_name:expr, () -> Result<$ok_type:ty, $err_type:ty>) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine) -> Result<$ok_type, $err_type> {
|
||||
match engine.eval::<$ok_type>(&format!("{}()", $rhai_func_name)) {
|
||||
Ok(result) => Ok(result),
|
||||
Err(err) => Err($err_type::from(format!("Rhai error: {}", err))),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Function with a Result return type and one argument
|
||||
($func_name:ident, $rhai_func_name:expr, ($arg1_type:ty) -> Result<$ok_type:ty, $err_type:ty>) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine, arg1: $arg1_type) -> Result<$ok_type, $err_type> {
|
||||
// Create a scope to pass arguments
|
||||
let mut scope = rhai::Scope::new();
|
||||
scope.push("arg1", arg1);
|
||||
|
||||
match engine.eval_with_scope::<$ok_type>(&mut scope, &format!("{}(arg1)", $rhai_func_name)) {
|
||||
Ok(result) => Ok(result),
|
||||
Err(err) => Err($err_type::from(format!("Rhai error: {}", err))),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Function with a Result return type and two arguments
|
||||
($func_name:ident, $rhai_func_name:expr, ($arg1_type:ty, $arg2_type:ty) -> Result<$ok_type:ty, $err_type:ty>) => {
|
||||
pub fn $func_name(engine: &mut rhai::Engine, arg1: $arg1_type, arg2: $arg2_type) -> Result<$ok_type, $err_type> {
|
||||
// Create a scope to pass arguments
|
||||
let mut scope = rhai::Scope::new();
|
||||
scope.push("arg1", arg1);
|
||||
scope.push("arg2", arg2);
|
||||
|
||||
match engine.eval_with_scope::<$ok_type>(&mut scope, &format!("{}(arg1, arg2)", $rhai_func_name)) {
|
||||
Ok(result) => Ok(result),
|
||||
Err(err) => Err($err_type::from(format!("Rhai error: {}", err))),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
// into a more general wrap_for_rhai! macro if patterns become too numerous or complex.
|
||||
// For now, separate macros are clear for distinct return type patterns.
|
||||
|
Reference in New Issue
Block a user