78 lines
3.5 KiB
Markdown
78 lines
3.5 KiB
Markdown
# 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):**
|
|
|
|
```rust
|
|
// 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):**
|
|
|
|
```rust
|
|
// 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:
|
|
1. Takes a `rhai::NativeCallContext` and an `i64` from the Rhai engine.
|
|
2. Attempts to convert the `i64` to the specified `rust_int_ty` using `try_into()`.
|
|
3. If conversion fails, it returns an `ErrorArithmetic` detailing the function/method name and the type conversion that failed.
|
|
4. If conversion succeeds, it calls the original Rust function/method with the converted value.
|
|
|
|
## Adding to Your Project
|
|
|
|
Add this to your `Cargo.toml`:
|
|
|
|
```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.
|