Rhai Embedded Scripting for Rust

repository·main·Indexed 26 days ago

https://github.com/rhaiscript/rhai

An embedded scripting language and evaluation engine for Rust (v1.25.1) featuring a syntax similar to JavaScript and Rust. It provides tight integration with native Rust types, AST compilation, and a plugin system via rhai_codegen. Designed for security with sandboxing and attack protection, Rhai supports WASM and no-std environments. Includes tools such as rhai-run, rhai-repl, and rhai-dbg.

Tokens
10.7K
Snippets
17
Records
65
Agent score
90%

What's inside Rhai

  1. Overview of rhai_codegen

    main

    The rhai_codegen crate provides procedural macros used for code generation within the Rhai plugin system. It is designed to facilitate the creation of plugins for the Rhai scripting engine.

    Note: This crate is automatically referenced by the main rhai crate. It is recommended that users do not use rhai_codegen directly unless they are specifically developing custom plugins that require these macros.

  2. Overview of Rhai Tools

    main

    Rhai provides several command-line tools for working with Rhai scripts. Note that some tools require specific Cargo features to be enabled during compilation or installation.

    ToolRequired feature(s)Description
    rhai-run(None)Runs each filename passed to it as a Rhai script
    rhai-replrustylineA simple REPL that interactively evaluates statements
    rhai-dbgdebuggingThe Rhai Debugger
  3. Overview of Rhai scripting engine

    main

    Rhai is an embedded scripting language and evaluation engine for Rust. It provides a safe and easy way to add scripting capabilities to Rust applications, featuring a syntax similar to JavaScript and Rust with dynamic typing.

    Key capabilities include:

    • Tight integration with native Rust functions, types, getters/setters, methods, and indexers.
    • Passing Rust values into scripts via an external Scope (supports all clonable Rust types).
    • Support for common data types: booleans, integers, floating-point numbers (including Decimal), strings, Unicode characters, arrays (including byte arrays), and object maps.
    • Ability to call script-defined functions from Rust.
    • Optimization via AST compilation and script optimization.
    • Custom API development through a plugin system using procedural macros.
    • Serialization/deserialization support via serde (requires the serde feature).
  4. Customize Rhai as a Domain Specific Language (DSL)

    main

    Rhai can be heavily customized to serve as a specialized DSL by restricting or extending its language features:

    • Disable Features: Disable specific language features like looping.
    • Restrict Syntax: Surgically disable specific keywords and operators.
    • Extend Syntax: Define custom operators or add custom syntax to the language.
    • Custom Operators: Define your own operators within the engine.
  5. Target platforms and requirements for Rhai

    main

    Rhai supports all CPU and O/S targets supported by Rust, including:

    • WebAssembly (WASM)
    • no-std environments

    Requirements:

    • Minimum Rust version: 1.66.0

    Note: stdweb is no longer supported for WASM builds due to changes in getrandom v0.3.

  6. Install Rhai Tools via Cargo

    main

    To install all Rhai tools with full functionality, use the bin-features feature flag. This flag enables decimal, metadata, serde, debugging, and rustyline support.

    To install all tools at once:

    cargo install --path . --bins --features bin-features

    To install a specific tool (replace sample_app_to_run with the desired binary name):

    cargo install --path . --bin sample_app_to_run --features bin-features
    cargo install --path . --bins  --features bin-features
  7. Run Rhai Tools during development

    main

    If you are working within the repository and want to run a tool using cargo run, ensure you include the bin-features flag to enable all tool-related capabilities.

    cargo run --features bin-features --bin sample_app_to_run
  8. Quickstart: Embed Rhai in Rust

    main

    To use Rhai, create an Engine instance, register any necessary external functions, and then evaluate your script using eval_file or eval.

    Example script (my_script.rhai):

    fn factorial(x) {
        if x == 1 { return 1; }
        x * factorial(x - 1)
    }
    
    compute(factorial(10))

    Rust implementation:

    use rhai::{Engine, EvalAltResult};
    
    fn main() -> Result<(), Box<EvalAltResult>>
    {
        // Define external function
        fn compute_something(x: i64) -> bool {
            (x % 40) == 0
        }
    
        // Create scripting engine
        let mut engine = Engine::new();
    
        // Register external function as 'compute'
        engine.register_fn("compute", compute_something);
    
        // Evaluate the script, expecting a 'bool' result
        let result: bool = engine.eval_file("my_script.rhai".into())?;
    
        assert_eq!(result, true);
    
        Ok(())
    }
    use rhai::{Engine, EvalAltResult};
    
    fn main() -> Result<(), Box<EvalAltResult>>
    {
        fn compute_something(x: i64) -> bool {
            (x % 40) == 0
        }
    
        let mut engine = Engine::new();
        engine.register_fn("compute", compute_something);
    
        let result: bool = engine.eval_file("my_script.rhai".into())?;
    
        assert_eq!(result, true);
    
        Ok(())
    }