3.5 KiB
Rhai Adapter Macros (adapter_macros
)
This crate provides utility macros to facilitate the integration of Rust code with the Rhai scripting engine, particularly for adapting function and method signatures.
Purpose
Rhai often uses i64
as its default integer type. When exposing Rust functions or methods that use other integer types (e.g., u32
, usize
), direct registration can lead to type mismatches or require manual conversion boilerplate in each registered function.
These macros help bridge this gap by wrapping your Rust functions/methods, automatically handling the conversion from Rhai's i64
to the Rust-native integer type and providing more informative error messages if the conversion fails (e.g., due to overflow).
Macros
1. adapt_rhai_i64_input_fn!(rust_fn:path, rust_int_ty:ty)
Adapts a standalone Rust function that takes a single argument of rust_int_ty
and returns Result<_, Box<rhai::EvalAltResult>>
.
rust_fn
: The path to your Rust function (e.g.,my_module::my_function
).rust_int_ty
: The integer type your Rust function expects (e.g.,u32
).
Example Usage in Rust (when registering with Rhai Engine):
// In your Rust code where you set up the Rhai engine:
// Assuming your_function(val: u32) -> Result<Something, Error> exists
// and adapter_macros is a dependency.
engine.register_fn("my_rhai_func", adapter_macros::adapt_rhai_i64_input_fn!(my_module::your_function, u32));
// In Rhai script:
// my_rhai_func(10); // 10 (i64) will be converted to u32 for your_function
2. adapt_rhai_i64_input_method!(struct_ty:ty, rust_method_name:ident, rust_int_ty:ty)
Adapts a Rust instance method that takes self
by value, a single integer argument of rust_int_ty
, and returns Self
. This is useful for builder-like patterns or methods that modify and return the instance.
struct_ty
: The type of the struct on which the method is defined (e.g.,MyStruct
).rust_method_name
: The identifier of the Rust method (e.g.,with_value
).rust_int_ty
: The integer type your Rust method's argument expects (e.g.,u16
).
Example Usage in Rust (when registering with Rhai Engine):
// In your Rust code:
// Assuming MyStruct has a method: fn with_value(self, val: u16) -> Self
// and adapter_macros is a dependency.
engine.register_fn("with_value", adapter_macros::adapt_rhai_i64_input_method!(MyStruct, with_value, u16));
// In Rhai script:
// let my_obj = MyStruct::new();
// my_obj.with_value(5); // 5 (i64) will be converted to u16 for MyStruct::with_value
Error Handling
If the i64
value from Rhai cannot be converted to rust_int_ty
(e.g., an i64
value of -1 is passed when u32
is expected, or a value too large for u16
), the macros will generate a rhai::EvalAltResult::ErrorArithmetic
with a descriptive message and the script position.
How It Works
The macros generate a closure that:
- Takes a
rhai::NativeCallContext
and ani64
from the Rhai engine. - Attempts to convert the
i64
to the specifiedrust_int_ty
usingtry_into()
. - If conversion fails, it returns an
ErrorArithmetic
detailing the function/method name and the type conversion that failed. - If conversion succeeds, it calls the original Rust function/method with the converted value.
Adding to Your Project
Add this to your Cargo.toml
:
[dependencies]
adapter_macros = { path = "../adapter_macros" } # Or version = "0.1.0" if published
rhai = "x.y.z" # Your rhai version
Ensure the path to adapter_macros
is correct if used locally.