db/_archive/adapter_macros/README.md
2025-06-03 21:51:21 +03:00

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:

  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:

[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.