Struct rhai::Engine[][src]

pub struct Engine {
    pub id: Option<String>,
    // some fields omitted
}
Expand description

Rhai main scripting engine.

use rhai::Engine;

let engine = Engine::new();

let result = engine.eval::<i64>("40 + 2")?;

println!("Answer: {}", result);  // prints 42

Currently, Engine is neither Send nor Sync. Use the sync feature to make it Send + Sync.

Fields

id: Option<String>

A unique ID identifying this scripting Engine.

Implementations

Engine public API

👎 Deprecated:

this function is volatile and may change

Register a function of the Engine.

WARNING - Low Level API

This function is very low level. It takes a list of TypeId’s indicating the actual types of the parameters.

Arguments are simply passed in as a mutable array of &mut Dynamic, The arguments are guaranteed to be of the correct types matching the TypeId’s.

To access a primary parameter value (i.e. cloning is cheap), use: args[n].clone().cast::<T>()

To access a parameter value and avoid cloning, use std::mem::take(args[n]).cast::<T>(). Notice that this will consume the argument, replacing it with ().

To access the first mutable parameter, use args.get_mut(0).unwrap()

Register a custom type for use with the Engine. The type must implement Clone.

Example
#[derive(Debug, Clone, Eq, PartialEq)]
struct TestStruct {
    field: i64
}

impl TestStruct {
    fn new() -> Self                    { TestStruct { field: 1 } }
    fn update(&mut self, offset: i64)   { self.field += offset; }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Use `register_fn` to register methods on the type.
engine.register_fn("update", TestStruct::update);

assert_eq!(
    engine.eval::<TestStruct>("let x = new_ts(); x.update(41); x")?,
    TestStruct { field: 42 }
);

Register a custom type for use with the Engine, with a pretty-print name for the type_of function. The type must implement Clone.

Example
#[derive(Clone)]
struct TestStruct {
    field: i64
}

impl TestStruct {
    fn new() -> Self { TestStruct { field: 1 } }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

assert_eq!(
    engine.eval::<String>("let x = new_ts(); type_of(x)")?,
    "rust_out::TestStruct"
);

// Register the custom type with a name.
engine.register_type_with_name::<TestStruct>("Hello");

// Register methods on the type.
engine.register_fn("new_ts", TestStruct::new);

assert_eq!(
    engine.eval::<String>("let x = new_ts(); type_of(x)")?,
    "Hello"
);

Register an iterator adapter for an iterable type with the Engine. This is an advanced feature.

Register a getter function for a member of a registered type with the Engine.

The function signature must start with &mut self and not &self.

Example
#[derive(Clone)]
struct TestStruct {
    field: i64
}

impl TestStruct {
    fn new() -> Self                { TestStruct { field: 1 } }
    // Even a getter must start with `&mut self` and not `&self`.
    fn get_field(&mut self) -> i64  { self.field }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register a getter on a property (notice it doesn't have to be the same name).
engine.register_get("xyz", TestStruct::get_field);

assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz")?, 1);

Register a getter function for a member of a registered type with the Engine. Returns Result<Dynamic, Box<EvalAltResult>>.

The function signature must start with &mut self and not &self.

Example
use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};

#[derive(Clone)]
struct TestStruct {
    field: i64
}

impl TestStruct {
    fn new() -> Self { TestStruct { field: 1 } }
    // Even a getter must start with `&mut self` and not `&self`.
    fn get_field(&mut self) -> Result<Dynamic, Box<EvalAltResult>> {
        Ok(self.field.into())
    }
}

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register a getter on a property (notice it doesn't have to be the same name).
engine.register_get_result("xyz", TestStruct::get_field);

assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz")?, 1);

Register a setter function for a member of a registered type with the Engine.

Example
#[derive(Debug, Clone, Eq, PartialEq)]
struct TestStruct {
    field: i64
}

impl TestStruct {
    fn new() -> Self                        { TestStruct { field: 1 } }
    fn set_field(&mut self, new_val: i64)   { self.field = new_val; }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register a setter on a property (notice it doesn't have to be the same name)
engine.register_set("xyz", TestStruct::set_field);

// Notice that, with a getter, there is no way to get the property value
assert_eq!(
    engine.eval::<TestStruct>("let a = new_ts(); a.xyz = 42; a")?,
    TestStruct { field: 42 }
);

Register a setter function for a member of a registered type with the Engine. Returns Result<(), Box<EvalAltResult>>.

Example
use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};

#[derive(Debug, Clone, Eq, PartialEq)]
struct TestStruct {
    field: i64
}

impl TestStruct {
    fn new() -> Self { TestStruct { field: 1 } }
    fn set_field(&mut self, new_val: i64) -> Result<(), Box<EvalAltResult>> {
        self.field = new_val;
        Ok(())
    }
}

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register a setter on a property (notice it doesn't have to be the same name)
engine.register_set_result("xyz", TestStruct::set_field);

// Notice that, with a getter, there is no way to get the property value
assert_eq!(
    engine.eval::<TestStruct>("let a = new_ts(); a.xyz = 42; a")?,
    TestStruct { field: 42 }
);

Short-hand for registering both getter and setter functions of a registered type with the Engine.

All function signatures must start with &mut self and not &self.

Example
#[derive(Clone)]
struct TestStruct {
    field: i64
}

impl TestStruct {
    fn new() -> Self                        { TestStruct { field: 1 } }
    // Even a getter must start with `&mut self` and not `&self`.
    fn get_field(&mut self) -> i64          { self.field }
    fn set_field(&mut self, new_val: i64)   { self.field = new_val; }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register a getter and a setter on a property
// (notice it doesn't have to be the same name)
engine.register_get_set("xyz", TestStruct::get_field, TestStruct::set_field);

assert_eq!(engine.eval::<i64>("let a = new_ts(); a.xyz = 42; a.xyz")?, 42);

Register an index getter for a custom type with the Engine.

The function signature must start with &mut self and not &self.

Panics

Panics if the type is Array or Map. Indexers for arrays, object maps and strings cannot be registered.

Example
#[derive(Clone)]
struct TestStruct {
    fields: Vec<i64>
}

impl TestStruct {
    fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
    // Even a getter must start with `&mut self` and not `&self`.
    fn get_field(&mut self, index: i64) -> i64 { self.fields[index as usize] }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register an indexer.
engine.register_indexer_get(TestStruct::get_field);

assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3);

Register an index getter for a custom type with the Engine. Returns Result<Dynamic, Box<EvalAltResult>>.

The function signature must start with &mut self and not &self.

Panics

Panics if the type is Array or Map. Indexers for arrays, object maps and strings cannot be registered.

Example
use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};

#[derive(Clone)]
struct TestStruct {
    fields: Vec<i64>
}

impl TestStruct {
    fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
    // Even a getter must start with `&mut self` and not `&self`.
    fn get_field(&mut self, index: i64) -> Result<Dynamic, Box<EvalAltResult>> {
        Ok(self.fields[index as usize].into())
    }
}

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register an indexer.
engine.register_indexer_get_result(TestStruct::get_field);

assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2]")?, 3);

Register an index setter for a custom type with the Engine.

Panics

Panics if the type is Array or Map. Indexers for arrays, object maps and strings cannot be registered.

Example
#[derive(Clone)]
struct TestStruct {
    fields: Vec<i64>
}

impl TestStruct {
    fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
    fn set_field(&mut self, index: i64, value: i64) { self.fields[index as usize] = value; }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register an indexer.
engine.register_indexer_set(TestStruct::set_field);

assert_eq!(
    engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?.fields[2],
    42
);

Register an index setter for a custom type with the Engine. Returns Result<(), Box<EvalAltResult>>.

Panics

Panics if the type is Array or Map. Indexers for arrays, object maps and strings cannot be registered.

Example
use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn};

#[derive(Clone)]
struct TestStruct {
    fields: Vec<i64>
}

impl TestStruct {
    fn new() -> Self { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
    fn set_field(&mut self, index: i64, value: i64) -> Result<(), Box<EvalAltResult>> {
        self.fields[index as usize] = value;
        Ok(())
    }
}

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register an indexer.
engine.register_indexer_set_result(TestStruct::set_field);

assert_eq!(
    engine.eval::<TestStruct>("let a = new_ts(); a[2] = 42; a")?.fields[2],
    42
);

Short-hand for register both index getter and setter functions for a custom type with the Engine.

Panics

Panics if the type is Array or Map. Indexers for arrays, object maps and strings cannot be registered.

Example
#[derive(Clone)]
struct TestStruct {
    fields: Vec<i64>
}

impl TestStruct {
    fn new() -> Self                                { TestStruct { fields: vec![1, 2, 3, 4, 5] } }
    // Even a getter must start with `&mut self` and not `&self`.
    fn get_field(&mut self, index: i64) -> i64      { self.fields[index as usize] }
    fn set_field(&mut self, index: i64, value: i64) { self.fields[index as usize] = value; }
}

use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register the custom type.
engine.register_type::<TestStruct>();

engine.register_fn("new_ts", TestStruct::new);

// Register an indexer.
engine.register_indexer_get_set(TestStruct::get_field, TestStruct::set_field);

assert_eq!(engine.eval::<i64>("let a = new_ts(); a[2] = 42; a[2]")?, 42);

Compile a string into an AST, which can be used later for evaluation.

Example
use rhai::Engine;

let engine = Engine::new();

// Compile a script to an AST and store it for later evaluation
let ast = engine.compile("40 + 2")?;

for _ in 0..42 {
    assert_eq!(engine.eval_ast::<i64>(&ast)?, 42);
}

Compile a string into an AST using own scope, which can be used later for evaluation.

The scope is useful for passing constants into the script for optimization when using OptimizationLevel::Full.

Example
use rhai::{Engine, Scope, OptimizationLevel};

let mut engine = Engine::new();

// Set optimization level to 'Full' so the Engine can fold constants
// into function calls and operators.
engine.set_optimization_level(OptimizationLevel::Full);

// Create initialized scope
let mut scope = Scope::new();
scope.push_constant("x", 42_i64);   // 'x' is a constant

// Compile a script to an AST and store it for later evaluation.
// Notice that `Full` optimization is on, so constants are folded
// into function calls and operators.
let ast = engine.compile_with_scope(&mut scope,
            "if x > 40 { x } else { 0 }"    // all 'x' are replaced with 42
)?;

// Normally this would have failed because no scope is passed into the 'eval_ast'
// call and so the variable 'x' does not exist.  Here, it passes because the script
// has been optimized and all references to 'x' are already gone.
assert_eq!(engine.eval_ast::<i64>(&ast)?, 42);

When passed a list of strings, first join the strings into one large script, and then compile them into an AST using own scope, which can be used later for evaluation.

The scope is useful for passing constants into the script for optimization when using OptimizationLevel::Full.

Note

All strings are simply parsed one after another with nothing inserted in between, not even a newline or space.

Example
use rhai::{Engine, Scope, OptimizationLevel};

let mut engine = Engine::new();

// Set optimization level to 'Full' so the Engine can fold constants
// into function calls and operators.
engine.set_optimization_level(OptimizationLevel::Full);

// Create initialized scope
let mut scope = Scope::new();
scope.push_constant("x", 42_i64);   // 'x' is a constant

// Compile a script made up of script segments to an AST and store it for later evaluation.
// Notice that `Full` optimization is on, so constants are folded
// into function calls and operators.
let ast = engine.compile_scripts_with_scope(&mut scope, &[
            "if x > 40",            // all 'x' are replaced with 42
            "{ x } el",
            "se { 0 }"              // segments do not need to be valid scripts!
])?;

// Normally this would have failed because no scope is passed into the 'eval_ast'
// call and so the variable 'x' does not exist.  Here, it passes because the script
// has been optimized and all references to 'x' are already gone.
assert_eq!(engine.eval_ast::<i64>(&ast)?, 42);

Compile a script file into an AST, which can be used later for evaluation.

Example
use rhai::Engine;

let engine = Engine::new();

// Compile a script file to an AST and store it for later evaluation.
// Notice that a PathBuf is required which can easily be constructed from a string.
let ast = engine.compile_file("script.rhai".into())?;

for _ in 0..42 {
    engine.eval_ast::<i64>(&ast)?;
}

Compile a script file into an AST using own scope, which can be used later for evaluation.

The scope is useful for passing constants into the script for optimization when using OptimizationLevel::Full.

Example
use rhai::{Engine, Scope, OptimizationLevel};

let mut engine = Engine::new();

// Set optimization level to 'Full' so the Engine can fold constants.
engine.set_optimization_level(OptimizationLevel::Full);

// Create initialized scope
let mut scope = Scope::new();
scope.push_constant("x", 42_i64);   // 'x' is a constant

// Compile a script to an AST and store it for later evaluation.
// Notice that a PathBuf is required which can easily be constructed from a string.
let ast = engine.compile_file_with_scope(&mut scope, "script.rhai".into())?;

let result = engine.eval_ast::<i64>(&ast)?;

Parse a JSON string into a map.

The JSON string must be an object hash. It cannot be a simple JavaScript primitive.

Set has_null to true in order to map null values to (). Setting it to false will cause a variable not found error during parsing.

JSON With Sub-Objects

This method assumes no sub-objects in the JSON string. That is because the syntax of a JSON sub-object (or object hash), { .. }, is different from Rhai’s syntax, #{ .. }. Parsing a JSON string with sub-objects will cause a syntax error.

If it is certain that the character { never appears in any text string within the JSON object, then globally replace { with #{ before calling this method.

Example
use rhai::{Engine, Map};

let engine = Engine::new();

let map = engine.parse_json(
    r#"{"a":123, "b":42, "c":{"x":false, "y":true}, "d":null}"#
        .replace("{", "#{").as_str(), true)?;

assert_eq!(map.len(), 4);
assert_eq!(map["a"].as_int().unwrap(), 123);
assert_eq!(map["b"].as_int().unwrap(), 42);
assert!(map["d"].is::<()>());

let c = map["c"].read_lock::<Map>().unwrap();
assert_eq!(c["x"].as_bool().unwrap(), false);

Compile a string containing an expression into an AST, which can be used later for evaluation.

Example
use rhai::Engine;

let engine = Engine::new();

// Compile a script to an AST and store it for later evaluation
let ast = engine.compile_expression("40 + 2")?;

for _ in 0..42 {
    assert_eq!(engine.eval_ast::<i64>(&ast)?, 42);
}

Compile a string containing an expression into an AST using own scope, which can be used later for evaluation.

The scope is useful for passing constants into the script for optimization when using OptimizationLevel::Full.

Example
use rhai::{Engine, Scope, OptimizationLevel};

let mut engine = Engine::new();

// Set optimization level to 'Full' so the Engine can fold constants
// into function calls and operators.
engine.set_optimization_level(OptimizationLevel::Full);

// Create initialized scope
let mut scope = Scope::new();
scope.push_constant("x", 10_i64);   // 'x' is a constant

// Compile a script to an AST and store it for later evaluation.
// Notice that `Full` optimization is on, so constants are folded
// into function calls and operators.
let ast = engine.compile_expression_with_scope(&mut scope,
            "2 + (x + x) * 2"    // all 'x' are replaced with 10
)?;

// Normally this would have failed because no scope is passed into the 'eval_ast'
// call and so the variable 'x' does not exist.  Here, it passes because the script
// has been optimized and all references to 'x' are already gone.
assert_eq!(engine.eval_ast::<i64>(&ast)?, 42);

Evaluate a script file.

Example
use rhai::Engine;

let engine = Engine::new();

// Notice that a PathBuf is required which can easily be constructed from a string.
let result = engine.eval_file::<i64>("script.rhai".into())?;

Evaluate a script file with own scope.

Example
use rhai::{Engine, Scope};

let engine = Engine::new();

// Create initialized scope
let mut scope = Scope::new();
scope.push("x", 42_i64);

// Notice that a PathBuf is required which can easily be constructed from a string.
let result = engine.eval_file_with_scope::<i64>(&mut scope, "script.rhai".into())?;

Evaluate a string.

Example
use rhai::Engine;

let engine = Engine::new();

assert_eq!(engine.eval::<i64>("40 + 2")?, 42);

Evaluate a string with own scope.

Example
use rhai::{Engine, Scope};

let engine = Engine::new();

// Create initialized scope
let mut scope = Scope::new();
scope.push("x", 40_i64);

assert_eq!(engine.eval_with_scope::<i64>(&mut scope, "x += 2; x")?, 42);
assert_eq!(engine.eval_with_scope::<i64>(&mut scope, "x += 2; x")?, 44);

// The variable in the scope is modified
assert_eq!(scope.get_value::<i64>("x").expect("variable x should exist"), 44);

Evaluate a string containing an expression.

Example
use rhai::Engine;

let engine = Engine::new();

assert_eq!(engine.eval_expression::<i64>("40 + 2")?, 42);

Evaluate a string containing an expression with own scope.

Example
use rhai::{Engine, Scope};

let engine = Engine::new();

// Create initialized scope
let mut scope = Scope::new();
scope.push("x", 40_i64);

assert_eq!(engine.eval_expression_with_scope::<i64>(&mut scope, "x + 2")?, 42);

Evaluate an AST.

Example
use rhai::Engine;

let engine = Engine::new();

// Compile a script to an AST and store it for later evaluation
let ast = engine.compile("40 + 2")?;

// Evaluate it
assert_eq!(engine.eval_ast::<i64>(&ast)?, 42);

Evaluate an AST with own scope.

Example
use rhai::{Engine, Scope};

let engine = Engine::new();

// Compile a script to an AST and store it for later evaluation
let ast = engine.compile("x + 2")?;

// Create initialized scope
let mut scope = Scope::new();
scope.push("x", 40_i64);

// Compile a script to an AST and store it for later evaluation
let ast = engine.compile("x += 2; x")?;

// Evaluate it
assert_eq!(engine.eval_ast_with_scope::<i64>(&mut scope, &ast)?, 42);
assert_eq!(engine.eval_ast_with_scope::<i64>(&mut scope, &ast)?, 44);

// The variable in the scope is modified
assert_eq!(scope.get_value::<i64>("x").expect("variable x should exist"), 44);

Evaluate a file, but throw away the result and only return error (if any). Useful for when you don’t need the result, but still need to keep track of possible errors.

Evaluate a file with own scope, but throw away the result and only return error (if any). Useful for when you don’t need the result, but still need to keep track of possible errors.

Evaluate a string, but throw away the result and only return error (if any). Useful for when you don’t need the result, but still need to keep track of possible errors.

Evaluate a string with own scope, but throw away the result and only return error (if any). Useful for when you don’t need the result, but still need to keep track of possible errors.

Evaluate an AST, but throw away the result and only return error (if any). Useful for when you don’t need the result, but still need to keep track of possible errors.

Evaluate an AST with own scope, but throw away the result and only return error (if any). Useful for when you don’t need the result, but still need to keep track of possible errors.

Call a script function defined in an AST with multiple arguments. Arguments are passed as a tuple.

Example
use rhai::{Engine, Scope};

let engine = Engine::new();

let ast = engine.compile(r"
    fn add(x, y) { len(x) + y + foo }
    fn add1(x)   { len(x) + 1 + foo }
    fn bar()     { foo/2 }
")?;

let mut scope = Scope::new();
scope.push("foo", 42_i64);

// Call the script-defined function
let result: i64 = engine.call_fn(&mut scope, &ast, "add", ( String::from("abc"), 123_i64 ) )?;
assert_eq!(result, 168);

let result: i64 = engine.call_fn(&mut scope, &ast, "add1", ( String::from("abc"), ) )?;
//                                                         ^^^^^^^^^^^^^^^^^^^^^^^^ tuple of one
assert_eq!(result, 46);

let result: i64 = engine.call_fn(&mut scope, &ast, "bar", () )?;
assert_eq!(result, 21);

Call a script function defined in an AST with multiple Dynamic arguments and optionally a value for binding to the ‘this’ pointer.

WARNING

All the arguments are consumed, meaning that they’re replaced by (). This is to avoid unnecessarily cloning the arguments. Do not use the arguments after this call. If they are needed afterwards, clone them before calling this function.

Example
use rhai::{Engine, Scope, Dynamic};

let engine = Engine::new();

let ast = engine.compile(r"
    fn add(x, y) { len(x) + y + foo }
    fn add1(x)   { len(x) + 1 + foo }
    fn bar()     { foo/2 }
    fn action(x) { this += x; }         // function using 'this' pointer
")?;

let mut scope = Scope::new();
scope.push("foo", 42_i64);

// Call the script-defined function
let result = engine.call_fn_dynamic(&mut scope, &ast, "add", None, [ String::from("abc").into(), 123_i64.into() ])?;
//                                                           ^^^^ no 'this' pointer
assert_eq!(result.cast::<i64>(), 168);

let result = engine.call_fn_dynamic(&mut scope, &ast, "add1", None, [ String::from("abc").into() ])?;
assert_eq!(result.cast::<i64>(), 46);

let result = engine.call_fn_dynamic(&mut scope, &ast, "bar", None, [])?;
assert_eq!(result.cast::<i64>(), 21);

let mut value: Dynamic = 1_i64.into();
let result = engine.call_fn_dynamic(&mut scope, &ast, "action", Some(&mut value), [ 41_i64.into() ])?;
//                                                              ^^^^^^^^^^^^^^^^ binding the 'this' pointer
assert_eq!(value.as_int().unwrap(), 42);

Optimize the AST with constants defined in an external Scope. An optimized copy of the AST is returned while the original AST is consumed.

Although optimization is performed by default during compilation, sometimes it is necessary to re-optimize an AST. For example, when working with constants that are passed in via an external scope, it will be more efficient to optimize the AST once again to take advantage of the new constants.

With this method, it is no longer necessary to recompile a large script. The script AST can be compiled just once. Before evaluation, constants are passed into the Engine via an external scope (i.e. with scope.push_constant(...)). Then, the `AST is cloned and the copy re-optimized before running.

Provide a callback that will be invoked before each variable access.

Return Value of Callback

Return Ok(None) to continue with normal variable access.
Return Ok(Some(Dynamic)) as the variable’s value.

Errors in Callback

Return Err(...) if there is an error.

Example
use rhai::Engine;

let mut engine = Engine::new();

// Register a variable resolver.
engine.on_var(|name, _, _, _| {
    match name {
        "MYSTIC_NUMBER" => Ok(Some(42_i64.into())),
        _ => Ok(None)
    }
});

engine.eval::<i64>("MYSTIC_NUMBER")?;

Register a callback for script evaluation progress.

Example
use rhai::Engine;

let result = Arc::new(RwLock::new(0_u64));
let logger = result.clone();

let mut engine = Engine::new();

engine.on_progress(move |&ops| {
    if ops > 10000 {
        false
    } else if ops % 800 == 0 {
        *logger.write().unwrap() = ops;
        true
    } else {
        true
    }
});

engine.consume("for x in range(0, 50000) {}")
    .expect_err("should error");

assert_eq!(*result.read().unwrap(), 9600);

Override default action of print (print to stdout using println!)

Example
use rhai::Engine;

let result = Arc::new(RwLock::new(String::from("")));

let mut engine = Engine::new();

// Override action of 'print' function
let logger = result.clone();
engine.on_print(move |s| logger.write().unwrap().push_str(s));

engine.consume("print(40 + 2);")?;

assert_eq!(*result.read().unwrap(), "42");

Override default action of debug (print to stdout using println!)

Example
use rhai::Engine;

let result = Arc::new(RwLock::new(String::from("")));

let mut engine = Engine::new();

// Override action of 'print' function
let logger = result.clone();
engine.on_debug(move |s| logger.write().unwrap().push_str(s));

engine.consume(r#"debug("hello");"#)?;

assert_eq!(*result.read().unwrap(), r#""hello""#);

Create a new Engine

Create a new Engine with minimal built-in functions. Use the load_package method to load additional packages of functions.

Make a Box<EvalAltResult>.

Load a new package into the Engine. Anything that can be converted into a PackageLibrary is accepted, including a simple Module.

When searching for functions, packages loaded later are preferred. In other words, loaded packages are searched in reverse order.

Control whether and how the Engine will optimize an AST after compilation.

Not available under the no_optimize feature.

The current optimization level. It controls whether and how the Engine will optimize an AST after compilation.

Not available under the no_optimize feature.

Set the maximum levels of function calls allowed for a script in order to avoid infinite recursion and stack overflows.

The maximum levels of function calls allowed for a script.

Set the maximum number of operations allowed for a script to run to avoid consuming too much resources (0 for unlimited).

The maximum number of operations allowed for a script to run (0 for unlimited).

Set the maximum number of imported modules allowed for a script.

The maximum number of imported modules allowed for a script.

Set the depth limits for expressions (0 for unlimited).

The depth limit for expressions (0 for unlimited).

The depth limit for expressions in functions (0 for unlimited).

Set the maximum length of strings (0 for unlimited).

The maximum length of strings (0 for unlimited).

Set the maximum length of arrays (0 for unlimited).

The maximum length of arrays (0 for unlimited).

Set the maximum length of object maps (0 for unlimited).

The maximum length of object maps (0 for unlimited).

Set the module resolution service used by the Engine.

Not available under the no_module feature.

Disable a particular keyword or operator in the language.

Examples

The following will raise an error during parsing because the if keyword is disabled and is recognized as a variable name!

use rhai::Engine;

let mut engine = Engine::new();

engine.disable_symbol("if");    // disable the 'if' keyword

engine.compile("let x = if true { 42 } else { 0 };")?;
//                      ^ 'if' is rejected as a reserved keyword

The following will raise an error during parsing because the += operator is disabled.

use rhai::Engine;

let mut engine = Engine::new();

engine.disable_symbol("+=");    // disable the '+=' operator

engine.compile("let x = 42; x += 1;")?;
//                            ^ unknown operator

Register a custom operator into the language.

The operator must be a valid identifier (i.e. it cannot be a symbol).

Examples
use rhai::{Engine, RegisterFn};

let mut engine = Engine::new();

// Register a custom operator called 'foo' and give it
// a precedence of 160 (i.e. between +|- and *|/).
engine.register_custom_operator("foo", 160).unwrap();

// Register a binary function named 'foo'
engine.register_fn("foo", |x: i64, y: i64| (x * y) - (x + y));

assert_eq!(
    engine.eval_expression::<i64>("1 + 2 * 3 foo 4 - 5 / 6")?,
    15
);

Register a custom syntax with the Engine.

  • keywords holds a slice of strings that define the custom syntax.
  • new_vars is the number of new variables declared by this custom syntax, or the number of variables removed (if negative).
  • func is the implementation function.

Trait Implementations

Formats the value using the given formatter. Read more

Returns the “default value” for a type. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Create a Rust closure from an AST. The Engine and AST are consumed and basically embedded into the closure. Read more

Create a Rust closure from a script. The Engine is consumed and basically embedded into the closure. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Register a custom fallible function with the Engine. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.