2.9 KiB
Architecture of the derive
Crate
The derive
crate is a procedural macro crate responsible for generating boilerplate code that integrates Rust structs with the Rhai scripting engine. It simplifies the process of exposing Rust types and their properties to Rhai scripts.
Core Functionality
The crate provides two main procedural macros:
#[derive(RhaiApi)]
#[derive(FromVec)]
#[derive(RhaiApi)]
This is the primary macro of the crate. When applied to a Rust struct, it automatically generates a Rhai-compatible DSL (Domain-Specific Language) for that struct.
Generated Code Structure
For a struct named MyStruct
, the macro generates a new module named my_struct_rhai_dsl
. This module contains a Rhai export_module
with the following functions:
new_my_struct()
: A constructor function that creates a new instance ofMyStruct
within the Rhai engine.- Setter Functions: For each field in
MyStruct
, a corresponding setter function is generated. For a field namedmy_field
, a Rhai functionmy_field(value)
is created to set its value. id()
: A function to retrieve the ID of the object.
This allows for a fluent, chainable API within Rhai scripts, like so:
let my_object = new_my_struct().field1(42).field2("hello");
Implementation Details
The implementation resides in src/rhai_api.rs
. It uses the syn
crate to parse the input DeriveInput
and the quote
crate to construct the output TokenStream
.
The process is as follows:
- The macro input is parsed into a
DeriveInput
AST (Abstract Syntax Tree). - The struct's name and fields are extracted from the AST.
- A new module name is generated based on the struct's name (e.g.,
MyStruct
->my_struct_rhai_dsl
). - Using the
quote!
macro, the code for the new module, theexport_module
, the constructor, and the setter functions is generated. - The generated code is returned as a
TokenStream
, which the compiler then incorporates into the crate.
Architectural Diagram
graph TD
A[Rust Struct Definition] -- `#[derive(RhaiApi)]` --> B{`derive` Crate};
B -- `syn` --> C[Parse Struct AST];
C -- Extract Fields & Name --> D[Generate Code with `quote`];
D -- Create --> E[Constructor `new_...()`];
D -- Create --> F[Setter Functions `field(...)`];
D -- Create --> G[`id()` function];
E & F & G -- Packaged into --> H[Rhai `export_module`];
H -- Returned as `TokenStream` --> I[Compiler];
I -- Integrates into --> J[Final Binary];
#[derive(FromVec)]
This is a simpler utility macro. Its purpose is to generate a From<Vec<T>>
implementation for a tuple struct that contains a single Vec<T>
. This is useful for converting a vector of items into a specific newtype-pattern struct.
Implementation
The implementation is located directly in src/lib.rs
. It parses the input struct and, if it's a single-element tuple struct, generates the corresponding From
implementation.