rhailib/src/derive/docs/ARCHITECTURE.md
2025-06-27 12:09:50 +03:00

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:

  1. #[derive(RhaiApi)]
  2. #[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 of MyStruct within the Rhai engine.
  • Setter Functions: For each field in MyStruct, a corresponding setter function is generated. For a field named my_field, a Rhai function my_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:

  1. The macro input is parsed into a DeriveInput AST (Abstract Syntax Tree).
  2. The struct's name and fields are extracted from the AST.
  3. A new module name is generated based on the struct's name (e.g., MyStruct -> my_struct_rhai_dsl).
  4. Using the quote! macro, the code for the new module, the export_module, the constructor, and the setter functions is generated.
  5. 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.