rhai-analyzer 0.1.1

Static analysis of Rhai ASTs: extracts accessed variable paths and string comparisons
Documentation
# rhai-analyzer

[![Crates.io](https://img.shields.io/crates/v/rhai-analyzer.svg)](https://crates.io/crates/rhai-analyzer)
[![Docs.rs](https://docs.rs/rhai-analyzer/badge.svg)](https://docs.rs/rhai-analyzer)
[![License](https://img.shields.io/crates/l/rhai-analyzer.svg)](https://crates.io/crates/rhai-analyzer)
[![Build Status](https://img.shields.io/github/actions/workflow/status/isSerge/rhai-analyzer/ci.yml?branch=main)](https://github.com/isSerge/rhai-analyzer/actions)

Static analysis utilities for [Rhai](https://rhai.rs/) scripts.

## Why this exists

`rhai-analyzer` provides a way to extract information from a compiled `rhai::AST` without executing it. This is useful for:
1.  **Dependency Tracking**: Identify which external variables or data paths a script depends on (e.g., `input.value`, `settings.mode`).
2.  **Schema Validation**: Ensure a script only accesses allowed variables.
3.  **Optimization**: Pre-calculate or pre-fetch data based on what the script is guaranteed (or likely) to access.

## Features

- **Variable Path Extraction**: Collects all unique, fully-qualified variable paths (e.g., `user.profile.name`) accessed in a script.
- **Local Variable Tracking**: Identifies variables defined within the script (via `let` or loop iterations) to distinguish them from external dependencies.
- **String Comparison Analysis**: Maps variable paths to the literal strings they are compared against (via `==` or `!=`).
- **Domain Agnostic**: The analyzer doesn't make assumptions about your data model—it just reports what it finds.

## Installation

### Add via Cargo

```bash
cargo add rhai-analyzer
```

### Manual Configuration

Add the following to your `Cargo.toml`:

```toml
[dependencies]
rhai-analyzer = "0.1.1"
rhai = { version = "1.25.0", features = ["internals"] }
```

## Usage

### 1. Extension trait (recommended)

Import `RhaiAnalyzerExt` to call analysis methods directly on any compiled
`rhai::AST`:

```rust
use rhai::Engine;
use rhai_analyzer::RhaiAnalyzerExt;

let engine = Engine::new();
let ast = engine.compile(r#"
    if request.amount > 100 && user.role == "admin" {
        let status = "approved";
    }
"#).unwrap();

// Which external variables does this script touch?
let vars = ast.accessed_variables();
assert!(vars.contains("request.amount"));
assert!(vars.contains("user.role"));

// What values is a specific variable compared against?
let roles = ast.string_comparisons_for("user.role");
assert!(roles.contains("admin"));
```

### 2. Full analysis pass

When you need all fields at once — accessed variables, local variables, and
string comparisons — call `analyze_ast` directly to avoid multiple traversals:

```rust
use rhai::Engine;
use rhai_analyzer::analyze_ast;

let engine = Engine::new();
let ast = engine.compile(r#"
    if request.amount > 100 && user.role == "admin" {
        let status = "approved";
        print(status);
    }
"#).unwrap();

let result = analyze_ast(&ast);

assert!(result.accessed_variables.contains("request.amount"));
assert!(result.local_variables.contains("status"));
assert!(result.string_comparisons["user.role"].contains("admin"));
```

### 3. Result data structure

```rust,ignore
    /// All unique, fully-qualified variable paths accessed in the script.
    pub accessed_variables: HashSet<String>,

    /// Local variables defined within the script via `let` or loops.
    pub local_variables: HashSet<String>,

    /// Maps a variable path to the set of string literals it is compared against.
    pub string_comparisons: HashMap<String, HashSet<String>>,
}
```

## License

* MIT license (http://opensource.org/licenses/MIT)