NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #3020 most downloaded on crates.io
Embedded scripting for Rust
Last release 8 days ago
10 Sep 2026
Ships fairly regularly
a new release about every 3 months
Nearly every release is documented
notes for 59 of the last 60 stable releases
9 versions withdrawn
withdrawn after publishing
11 years old
105 releases · first in 2016
This version adds string interpolation with ` ... ${ ... } ... ` syntax.
This version adds string interpolation with `... ${ ... } ...` syntax.
switch statement cases can now have conditions.
Negative indices for arrays and strings are allowed and now count from the end (-1 = last item/character).
Array::drain method with range is fixed._ case of a switch statement now must be the last case, together with two new error variants: EvalAltResult::WrongSwitchDefaultCase and EvalAltResult::WrongSwitchCaseCondition.ModuleResolver trait methods take an additional parameter source_path that contains the path of the current environment. This is to facilitate loading other script files always from the current directory.FileModuleResolver now resolves relative paths under the source path if there is no base path set.FileModuleResolver::base_path now returns Option<&str> which is None if there is no base path set.metadata feature.Array::drain and Array::retain methods with predicate now scan the array in forward order instead of in reverse. `... ${ ... } ...` syntax.FileModuleResolver resolves relative paths under the parent path (i.e. the path holding the script that does the loading). This allows seamless cross-loading of scripts from a directory hierarchy instead of having all relative paths load from the current working directory.switch statement cases can now have an optional if clause.One column per quarter.
This version replaces all internal usage of HashMap with BTreeMap, which should result in some speed improvement because a BTreeMap is leaner when the
This version replaces all internal usage of HashMap with BTreeMap, which should result
in some speed improvement because a BTreeMap is leaner when the number of items held is small.
Most, if not all, collections in Rhai hold very few data items, so this is a typical scenario of
many tiny-sized collections.
The Rhai object map type, Map, used to be an alias to HashMap and is now aliased to BTreeMap
instead. This is also because, in the vast majority of usage cases, the number of properties held by
an object map is small.
HashMap and BTreeMap have almost identical public API's so this change is unlikely to break
existing code.
SmartString is used to store identifiers (which tend to
be short, fewer than 23 characters, and ASCII-based) because they can usually be stored inline.
Map keys now also use SmartString.
In addition, there is now support for line continuation in strings (put \ at the end of line) as
well as multi-line literal strings (wrapped by back-ticks: `...`).
Finally, all function signature/metadata methods are now grouped under the umbrella metadata feature.
This avoids spending precious resources maintaining metadata for functions for the vast majority of
use cases where such information is not required.
no_index + no_object now compile without errors.RegisterFn and RegisterResultFn are removed. Engine::register_fn and Engine::register_result_fn are now implemented directly on Engine.FnPtr::call_dynamic now takes &NativeCallContext instead of consuming it.Module::set_fn_XXX methods are removed, in favor of Module::set_native_fn.Array::reduce and Array::reduce_rev now take a Dynamic as initial value instead of a function pointer.protected, super are now reserved keywords.Module::set_fn_XXX API now take &str as the function name instead of Into<String>.Engine::gen_fn_signatures, Module::update_fn_metadata etc. are put under the metadata feature gate.#! is now a reserved symbol.SmartString is used for identifiers by default. Currently, a PR branch is pulled for no-std builds. The official crate will be used once SmartString is fixed to support no-std.Map is now an alias to BTreeMap<SmartString, Dynamic> instead of HashMap because most object maps hold few properties.EvalAltResult::FnWrongDefinition is renamed WrongFnDefinition for consistency.\) and multi-line literal strings (wrapped with `) support are added.#! which is ignored.HashMap usage with BTreeMap for better performance because collections in Rhai are tiny.Engine::register_result_fn no longer requires the successful return type to be Dynamic. It can now be any clonable type.#[rhai_fn(return_raw)] can now return Result<T, Box<EvalAltResult> > where T is any clonable
type instead of Result<Dynamic, Box<EvalAltResult> >.Dynamic::clone_cast is added to simplify casting from a &Dynamic.This version runs faster due to optimizations done on AST node structures. It also fixes a number of panic bugs related to passing shared values as fu
This version runs faster due to optimizations done on AST node structures. It also fixes a number of panic bugs related to passing shared values as function call arguments.
&str argument is fixed.switch statements on custom types is fixed.range(from, to, step) is fixed.&mut String parameters in registered functions no longer panic when passed a string.x in shared_value, return shared_value, obj.field = shared_value etc. Previously, the resultant value is still shared which is counter-intuitive.EvalAltResult::ErrorMismatchDataType which were swapped.Dynamic::as_str is removed because it does not properly handle shared values.range function now raises an error instead of creating an infinite stream.catch is now an object map containing error fields.EvalAltResult::clear_position is renamed EvalAltResult::take_position and returns the position taken.private functions in an AST can now be called with call_fn etc.NativeCallContext::call_fn_dynamic_raw no longer has the pub_only parameter.Module::update_fn_metadata input parameter is changed.type_of, eval, Fn) can no longer be overloaded. It is more trouble than worth. To disable these keywords, use Engine::disable_symbol.is_def_var and is_def_fn are now reserved keywords.Engine::id field is removed because it is never used.num-traits is now a required dependency.in operator is now implemented on top of the contains function and is no longer restricted to a few specific types.EvalAltResult::ErrorInExpr is removed because the in operator now calls contains.AST::walk, Expr::walk, Stmt::walk and ASTNode::walk and the callbacks they take now return bool to optionally terminate the recursive walk.range function now supports negative step and decreasing streams (i.e. to < from).catch statement in an object map.private functions in an AST cannot be called with call_fn etc. This is inconvenient when trying to call a function inside a script which also serves as a loadable module exporting part (but not all) of the functions. Now, all functions (private or not) can be called in an AST. The private keyword is relegated to preventing a function from being exported.Dynamic::as_unit just for completeness sake.bytes method added for strings to get length quickly (if the string is ASCII-only).FileModuleResolver can now enable/disable caching.AST can now be terminated in the middle.This version introduces functions with Dynamic parameters acting as wildcards.
This version introduces functions with Dynamic parameters acting as wildcards.
Position::is_beginning_of_line is fixed.&mut parameter) now raise an error unless the functions are marked with #[rhai_fn(pure)].pub or not) for generated plugin modules now follow the visibility of the underlying module.Engine::call_fn_dynamic takes an additional parameter to optionally evaluate the given AST before calling the function.Dynamic arguments.#[rhai_fn(pure)] attribute to mark a plugin function with &mut parameter as pure so constants can be passed to it. Without it, passing a constant value into the &mut parameter will now raise an error.FLOAT/Decimal and INT are now implemented for more speed under those cases.eval statements is now wrapped in an EvalAltResult::ErrorInFunctionCall.Position now implements Add and AddAssign.Scope now implements IntoIterator.-/-= operators and the remove method to delete a sub-string/character.split_rev method and variations of split with maximum number of segments.split method.FLOAT/Decimal and INT are now built in.char are now built in.Engine::call_fn_dynamic can now optionally evaluate the given AST before calling the function.Notice that there are a number of breaking changes, especially with regards to replacing the ~ exponential operator with , and the addition of the dec…
This version is an incremental release with a number of enhancements and bug fixes.
Notice that there are a number of breaking changes, especially with regards to replacing the ~
exponential operator with **, and the addition of the decimal feature that turns on
Decimal support.
;) now parse correctly and no longer hang.continue, break and return statements no longer panic inside a try .. catch block.round function for f64 is now implemented correctly.~ to **; ~ is now a reserved symbolDynamic::into_shared is no longer available under no_closure. It used to panic.Token::is_operator is renamed to Token::is_symbol.AST::clone_functions_only_filtered, AST::merge_filtered, AST::combine_filtered and AST::retain_functions now take Fn instead of FnMut as the filter predicate.decimal, enables the Decimal data type. When both no_float and decimal features are enabled, floating-point literals parse to Decimal.atan(x, y) and hypot(x, y) to BasicMathPackage.FLOAT/Decimal and INT.This version streamlines compiling for WASM.
This version streamlines compiling for WASM.
Rust compiler minimum version is raised to 1.49.
metadata feature build.! operators now work properly.insert method for arrays is fixed.NativeCallContext::new taker an additional parameter containing the name of the function called.Engine::set_doc_comments is renamed Engine::enable_doc_comments.wasm-bindgen and stdweb, to specify the JS interop layer for WASM builds. wasm-bindgen used to be required.ahash is used to hash function call parameters. This should yield speed improvements.Dynamic and ImmutableString now implement serde::Serialize and serde::Deserialize.NativeCallContext has a new field containing the name of the function called, useful when the same Rust function is registered under multiple names in Rhai.PI() and E() to return mathematical constants, and to_radians and to_degrees to convert between radians and degrees.no_std feature now compiles correctly (bug introduced in 0.19.9).
no_std feature now compiles correctly (bug introduced in 0.19.9).FileModuleResolver::clear_cache_for_path path mapping fixed.eval is present.EvalAltResult::ErrorInFunctionCall has a new parameter holding the source of the function.ParseErrorType::WrongFnDefinition is renamed FnWrongDefinition.ParseErrorType::FnDuplicatedDefinition. This is to prevent accidental overwriting an earlier function definition.AST::set_source is now split into AST::set_source and AST::clear_source.Engine::compile_into_self_contained compiles a script into an AST and eagerly resolves all import statements with string literal paths. The resolved modules are directly embedded into the AST. When the AST is later evaluated, import statements directly yield the pre-resolved modules without going through the resolution process once again.AST::walk, Stmt::walk and Expr::walk internal API's to recursively walk an AST.NativeCallContext for native Rust functions.EvalAltResult::clear_position to clear the position information of an error - useful when only the message is needed and the position doesn't need to be printed out.resolve_ast is added to the ModuleResolver trait for advanced usage.This version fixes a bug introduced in 0.19.8 which breaks property access within closures.
This version fixes a bug introduced in 0.19.8 which breaks property access
within closures.
It also removes the confusing differences between packages and modules by unifying the terminology and API under the global umbrella of modules.
Engine::set_max_call_levels.Engine::load_package is renamed Engine::register_global_module and now must explicitly pass a shared [Module].Engine::register_module is renamed Engine::register_static_module and now must explicitly pass a shared [Module].Package::get is renamed Package::as_shared_module.Engine::set_module_resolver now takes a straight module resolver instead of an Option. To disable module resolving, use the new DummyModuleResolver.Scope is now Clone + Hash.Engine::register_static_module now supports sub-module paths (e.g. foo::bar::baz).Engine::register_custom_operator now accepts reserved symbols.Engine::register_custom_operator now returns an error if given a precedence of zero.repl and rhai_runner are moved into bin and renamed rhai-repl and rhai-run respectively.This version makes it easier to generate documentation for a Rhai code base.
This version makes it easier to generate documentation for a Rhai code base.
Each function defined in an AST can optionally attach doc-comments (which, as in Rust,
are comments prefixed by either /// or /**). Doc-comments allow third-party tools to
automatically generate documentation for functions defined in a Rhai script.
A new API, Engine::gen_fn_metadata_to_json and Engine::gen_fn_metadata_with_ast_to_json,
paired with the new metadata feature, exports the full list of functions metadata
(including those in an AST) as a JSON document.
There are also a sizable number of bug fixes.
-, + and ! now bind correctly when applied to an expression. Previously, -x.len is parsed as (-x).len which is obviously counter-intuitive.path::to::var[x].this parameter to Rhai functions now throws an error if assigned to.Engine::register_iterator is IntoIterator instead of Iterator.**/ or inner blocks starting with //*.Engine::on_progress now takes u64 instead of &u64.Engine::on_debug now takes two additional parameters: source: Option<&str> and pos: Position.AST::iter_functions now returns ScriptFnMetadata.Engine::register_custom_syntax_raw now takes an additional parameter containing the look-ahead symbol.AST::iter_functions now returns ScriptFnMetadata which includes, among others, doc-comments for functions prefixed by /// or /**.Engine::set_doc_comments method.metadata is added that pulls in serde_json and enables Engine::gen_fn_metadata_to_json and Engine::gen_fn_metadata_with_ast_to_json which exports the full list of functions metadata (including those inside an AST) in JSON format.Engine::on_debug provides two additional parameters: source: Option<&str> and pos: Position, containing the current source (if any) and position of the debug statement.NativeCallContext and EvalContext both expose source() which returns the current source, if any.Fixes compilation errors with certain feature flag combinations.
#[rhai_fn(global)].to_debug is a new standard function for converting a value into debug format.to_debug (if available).This version adds the switch statement.
This version adds the switch statement.
It also allows exposing selected module functions (usually methods) to the global namespace. This is very convenient when encapsulating the API of a custom Rust type into a module while having methods and iterators registered on the custom type work normally.
A new gen_fn_signatures API enables enumerating the registered functions of an Engine for documentation purposes.
It also prepares the way for a future reflection API.
Module::set_fn, Module::set_raw_fn and Module::set_fn_XXX_mut all take an additional parameter of FnNamespace.Module::set_fn takes a further parameter with a list of parameter names/types plus the function return type, if any.Module::get_sub_module_mut is removed.begin, end, unless are now reserved keywords.EvalPackage is removed in favor of Engine::disable_symbol.switch statement.do ... while and do ... until statements.Engine::gen_fn_signatures, Module::gen_fn_signatures and PackagesCollection::gen_fn_signatures to generate a list of signatures for functions registered.Engine::register_static_module to register a module as a sub-module in the global namespace.set_exported_global_fn! macro to register a plugin function and expose it to the global namespace.Module::set_fn_XXX_mut can expose a module function to the global namespace. This is convenient when registering an API for a custom type.Module::set_getter_fn, Module::set_setter_fn, Module::set_indexer_get_fn, Module::set_indexer_set_fn all expose the function to the global namespace by default. This is convenient when registering an API for a custom type.Module::update_fn_metadata to update a module function's parameter names and types.#[rhai_fn(global)] and #[rhai_fn(internal)] attributes to determine whether a function defined in a plugin module should be exposed to the global namespace. This is convenient when defining an API for a custom type.get_fn_metadata_list to get the metadata of all script-defined functions in scope.Dynamic including UNIT, TRUE, FALSE, ZERO, ONE etc.0 are supported.This version fixes a bug that prevents compilation with the internals feature. It also speeds up importing modules.
This version fixes a bug that prevents compilation with the internals feature.
It also speeds up importing modules.
internals feature. Bug introduced in 0.19.4.ModuleResolver::resolve now returns Shared<Module> for better resources sharing when loading modules.ParseErrorType::DuplicatedExport is removed as multiple export's are now allowed.import statements at global level can now be used in functions. There is no longer any need to re-import the modules at the beginning of each function block.import statements are encapsulated into the AST when loading a module from a script file.export keyword can now be tagged onto let and const statements as a short-hand, e.g.: export let x = 42;export-ed multiple times under different names.index_of, == and != are defined for arrays.== and != are defined for object maps.This version basically cleans up the code structure in preparation for a potential 1.0 release in the future. Most scripts should see a material speed
This version basically cleans up the code structure in preparation for a potential 1.0 release in the future.
Most scripts should see a material speed increase.
This version also adds a low-level API for more flexibility when defining custom syntax.
Send + Sync for EvalAltResult under the sync feature. Bug introduced with 0.19.3.EvalAltResult::ErrorAssignmentToUnknownLHS is moved to ParseError::AssignmentToInvalidLHS. ParseError::AssignmentToCopy is removed.EvalAltResult::ErrorDataTooLarge is simplified.Engine::on_progress closure signature now returns Option<Dynamic> with the termination value passed on to EvalAltResult::ErrorTerminated.ParseErrorType::BadInput now wraps a LexError instead of a text string.f32_float feature to set FLOAT to f32.Module::fill_with to poly-fill a module with another.Engine::on_progress can now pass on a value as a termination token.Expr and Stmt are packed into smaller sizes (16 bytes and 32 bytes on 64-bit), stored inline for more cache friendliness, and de-Boxed as much as possible.Scope is optimized for cache friendliness.This version streamlines some of the advanced API's, and adds the try ... catch statement to catch exceptions.
This version streamlines some of the advanced API's, and adds the try ... catch statement
to catch exceptions.
EvalAltResult::ErrorReadingScriptFile is removed in favor of the new EvalAltResult::ErrorSystem.EvalAltResult::ErrorLoopBreak is renamed to EvalAltResult::LoopBreak.Engine::register_raw_fn and FnPtr::call_dynamic function signatures have changed.Engine::on_var and Engine::register_custom_syntax have changed.EvalAltResult::ErrorRuntime now wraps a Dynamic instead of a string.debug builds is reduced to 8 (from 12) because it keeps overflowing the stack in GitHub CI!thread is reserved.NativeCallContext as the first parameter.throw statement can now throw any value instead of just text strings.try ... catch statement to catch exceptions.eval or Fn in method-call style, which is an error, is now caught during parsing.func!() call style is valid even under no_closure feature.Bug fix on call module functions.
Bug fix on call module functions.
This version adds a variable resolver with the ability to short-circuit variable access, plus a whole bunch of array methods.
This version adds a variable resolver with the ability to short-circuit variable access, plus a whole bunch of array methods.
AST::iter_functions now returns an iterator instead of taking a closure.Module::get_script_function_by_signature renamed to Module::get_script_fn and returns &<Shared<ScriptFnDef> >.Module::num_fn, Module::num_var and Module::num_iter are removed and merged into Module::count.merge_namespaces parameter to Module::eval_ast_as_new is removed and now defaults to true.GlobalFileModuleResolver is removed because its performance gain over the FileModuleResolver is no longer very significant.EvalAltResult variants are removed and merged into EvalAltResult::ErrorMismatchDataType: ErrorCharMismatch, ErrorNumericIndexExpr, ErrorStringIndexExpr, ErrorImportExpr, ErrorLogicGuard, ErrorBooleanArgMismatchScope::iter_raw returns an iterator with an additional field indicating whether the variable is constant or not.rhai::ser and rhai::de namespaces are merged into rhai::serde.++, --, .., ....debug builds is reduced to 12 (from 16).~ is raised, while in is moved below logic comparison operators.Engine::on_var to register a variable resolver.const statements can now take any expression (or none at all) instead of only constant values.OptimizationLevel::Simple now eagerly evaluates built-in binary operators of primary types (if not overloaded).is_def_var() to detect if variable is defined, and is_def_fn() to detect if script function is defined.Dynamic::from(&str) now constructs a Dynamic with a copy of the string as value.AST::combine and AST::combine_filtered allows combining two AST's without creating a new one.map, filter, reduce, reduce_rev, some, all, extract, splice, chop and sort functions for arrays.Module::set_iterable and Module::set_iterator to define type iterators more easily. Engine::register_iterator is changed to use the simpler version.#[inline] or [inline(always)], just in case it helps when LTO is not turned on.The major new feature for this version is _Plugins_ support, powered by procedural macros. Plugins make it extremely easy to develop and register Rust
The major new feature for this version is Plugins support, powered by procedural macros.
Plugins make it extremely easy to develop and register Rust functions with an Engine.
if statement with an empty true block would not evaluate the false block. This is now fixed.Module::set_fn_4_mut.&str and String parameters.no_object.+=) now work correctly.Engine::register_set_result and Engine::register_indexer_set_result now take a function that returns Result<(), Box<EvalAltResult> >.Engine::register_indexer_XXX and Module::set_indexer_XXX panic when the type is Array, Map or String.EvalAltResult has a new variant ErrorInModule which holds errors when loading an external module.Module::eval_ast_as_new now takes an extra boolean parameter, indicating whether to encapsulate the entire module into a separate namespace.FileModuleResolver loaded modules now can cross-call each other in addition to functions in the global namespace. For the old behavior, use MergingFileModuleResolver instead.EvalAltResult::ErrorInModule variant capturing errors when loading a module from a script file.parse_int and parse_float functions for parsing numbers; split function for splitting strings.AST::iter_functions and Module::iter_script_fn_info to iterate functions.AST and Module now take FnMut instead of Fn.FileModuleResolver that encapsulates the entire AST of the module script, allowing function cross-calling. The old version is renamed MergingFileModuleResolver.+ and - operators for timestamps to increment/decrement by seconds.Engine::compile_expression, Engine::eval_expression etc. no longer parse anonymous functions and closures.
Engine::compile_expression, Engine::eval_expression etc. no longer parse anonymous functions and closures.no_object.Module::combine_flatten to combine two modules while flattening to the root level.Fixes bug that prevents calling functions in closures.
Module::contains_fn and Module::get_script_fn no longer take the public_only parameter.Engine::register_get_result, Engine::register_set_result, Engine::register_indexer_get_result, Engine::register_indexer_set_result API.Module::combine to combine two modules.Engine::parse_json now also accepts a JSON object starting with #{.Anonymous functions (in Rust closure syntax). Simplifies creation of single-use ad-hoc functions.
This version adds:
no_closure feature to disable sharing values and capturing.this pointer in a function pointer call.func!(...) syntax.call can now be called function-call style for function pointers - this is to handle builds with no_object.print, eval, call, this etc.x.call(f, ...) allows binding x to this for the function referenced by the function pointer f.|x, y, z| x + y - z.internals feature.curry keyword.func!(...) syntax.Module::set_indexer_get_set_fn is added as a short-hand of both Module::set_indexer_get_fn and Module::set_indexer_set_fn.unicode-xid-ident feature to allow Unicode Standard Annex #31 for identifiers.Scope::iter_raw returns an iterator with a reference to the underlying Dynamic value (which may be shared).Engine::register_raw_fn_XXX API shortcuts are removed.PackagesCollection::get_fn, PackagesCollection::contains_fn, Module::get_fn and Module::contains_fn now take an additional public_only parameter indicating whether only public functions are accepted.Scope::iter now contains a clone of the Dynamic value (unshared).Engine::register_global_module takes any type that is Into<PackageLibrary>.Engine::register_custom_syntax is no longer Box-ed.Nothing published for this version
`serde` support for working with Dynamic values (particularly _object maps_).
This version adds:
serde support for working with Dynamic values (particularly object maps).EvalAltResult::ErrorMismatchOutputType has an extra argument containing the name of the requested type.Engine::call_fn_dynamic take an extra argument, allowing a Dynamic value to be bound to the this pointer.% (modulo) operator is lowered to below bit shifts. This is to handle the case of x < < 3 % 10.serde feature to allow serializing/deserializing to/from Dynamic values using serde.
This is particularly useful when converting a Rust struct to a Dynamic object map and back.Engine::disable_symbol to surgically disable keywords and/or operators.Engine::register_custom_operator to define a custom operator.Engine::register_custom_syntax to define a custom syntax.Engine::register_raw_fn.Module::set_raw_fn mirroring Engine::register_raw_fn.AST::clone_functions_only, AST::clone_functions_only_filtered and AST::clone_statements_only to clone only part of an AST.^ (XOR) operator is added.FnPtr is exposed as the function pointer type.rhai::module_resolvers::ModuleResolversCollection added to try a list of module resolvers.&mut Self so that the calls can be chained.String parameters in functions are supported (but inefficiently).Bug fix release to fix errors when compiling with features.
Bug fix release to fix errors when compiling with features.
The major new feature in this version is OOP - well, poor man's OOP, that is.
The major new feature in this version is OOP - well, poor man's OOP, that is.
The README is officially transferred to The Rhai Book.
An online Playground is available.
ModuleResolver::resolve no longer takes a Scope as argument.this parameter instead of consuming the first parameter.Scope. Scope::push_module is removed.
Therefore, cannot rely on module imports to persist across invocations using a Scope.AST::retain_functions is used for another purpose. The old AST::retain_functions is renamed to AST::clear_statements.Fn(name) and Fn.call(...) syntax - a poor man's first-class function.this binding to the object.AST API for fine-tuned manipulation of functions.README was transferred to the Book.internals to expose internal data structures (e.g. the AST nodes).This is a minor release which enables updating indexers (via registered indexer setters) and supports functions with &str parameters (maps transparent
This is a minor release which enables updating indexers (via registered indexer setters) and supports functions
with &str parameters (maps transparently to ImmutableString). WASM is also a tested target.
let s="abc"; s[1].change_to('X'); now correctly sets the character 'X' into 's' yielding "aXc".Engine::on_progress now takes &u64 instead of u64 to be consistent with other callback signatures.Engine::register_indexer is renamed to Engine::register_indexer_get.Module::set_indexer_fn is renamed to Module::set_indexer_get_fn.ParseError now exposes the internal fields and the ParseError::error_type and ParseError::position methods are removed. The first tuple field is the ParseErrorType and the second tuple field is the Position.Engine::call_fn_dynamic now takes any type that implements IntoIterator<Item = Dynamic>.Engine::register_indexer_get and Engine::register_indexer_set with Engine::register_indexer_get_set being a short-hand. Similarly, Module::set_indexer_get_fn and Module::set_indexer_set_fn are added.Engine:register_fn and Engine:register_result_fn accepts functions that take parameters of type &str (immutable string slice), which maps directly to ImmutableString. This is to avoid needing wrappers for functions taking string parameters.Engine::set_max_string_size, Engine::set_max_array_size and Engine::set_max_map_size.This version uses immutable strings (ImmutableString type) and built-in operator functions (e.g. +, >, +=) to improve speed, plus some bug fixes.
This version uses immutable strings (ImmutableString type) and built-in operator functions (e.g. +, >, +=) to improve speed, plus some bug fixes.
eval_expression - it is assumed to be one-off and short.let s = "hello"; s[s.len-1] = 'x'; now works property instead of causing a runtime error.if expressions are not supposed to be allowed when compiling for expressions only. This is fixed.Engine::compile_XXX functions now return ParseError instead of Box<ParseError>.RegisterDynamicFn trait is merged into the RegisterResultFn trait which now always returns RhaiResult.Engine::new_raw.rhai::ImmutableString is used instead of std::string::String. This is to avoid excessive cloning of strings. All native-Rust functions taking string parameters should switch to rhai::ImmutableString (which is either Rc<String> or Arc<String> depending on whether the sync feature is used).Engine also mutates the first argument when called in normal function-call style (previously the first argument will be passed by value if not called in method-call style). Of course, if the first argument is a calculated value (e.g. result of an expression), then mutating it has no effect, but at least it is not cloned.len for string, floor for FLOAT) now have property versions in addition to methods to simplify coding.EvalPackage to disable eval.Module::set_getter_fn, Module::set_setter_fn and Module:set_indexer_fn to register getter/setter/indexer functions.Engine::call_fn_dynamic for more control in calling script functions.+, >, ==) now call into highly efficient built-in implementations for standard types (i.e. INT, FLOAT, bool, char, () and ImmutableString) if not overridden by a registered function. This yields a 5-10% speed benefit depending on script operator usage. Scripts running tight loops will see significant speed-up.+=, %=) now call into highly efficient built-in implementations for standard types (i.e. INT, FLOAT, bool, char, () and ImmutableString) if not overridden by a registered function.ArithmeticPackage and LogicPackage (and therefore the CorePackage) because they are now always available, even under Engine::new_raw.+=) are now handled directly and much faster.rhai::ImmutableString type, eliminating large amounts of cloning.&mut parameter, the first argument is passed by reference instead of by value, even if not called in method-call style. This allows many functions declared with &mut parameter to avoid excessive cloning. For example, if a is a large array, getting its length in this manner: len(a) used to result in a full clone of a before taking the length and throwing the copy away. Now, a is simply passed by reference, avoiding the cloning altogether.u64 keys without hashing to avoid function call hash keys (which are by themselves u64) being hashed twice.The major features for this release is modules, script resource limits, and speed improvements (mainly due to avoiding allocations).
The major features for this release is modules, script resource limits, and speed improvements (mainly due to avoiding allocations).
export variables and private functions.Engine::compile_scripts_with_scope, can compile a list of script segments without needing to first concatenate them together into one large string.range function with a custom step.StaticVecA script contains many lists - statements in a block, arguments to a function call etc.
In a typical script, most of these lists tend to be short - e.g. the vast majority of function calls contain
fewer than 4 arguments, while most statement blocks have fewer than 4-5 statements, with one or two being
the most common. Before, dynamic Vec's are used to hold these short lists for very brief periods of time,
causing allocations churn.
In this version, large amounts of allocations are avoided by converting to a StaticVec -
a list type based on a static array for a small number of items (currently four) -
wherever possible plus other tricks. Most real-life scripts should see material speed increases.
Almost all variable lookups, as well as lookups in loaded modules, are now pre-computed. A variable's name is almost never used to search for the variable in the current scope.
Getters and setter function names are also pre-computed and cached, so no string allocations are performed during a property get/set call.
Lookup of all function calls, including Rust and Rhai ones, are now through pre-computed hashes. The function name is no longer used to search for a function, making function call dispatches much faster.
The expression (Expr) and statement (Stmt) types are modified so that all of the variants contain only
one single Box to a large allocated structure containing all the fields. This makes the Expr and
Stmt types very small (only one single pointer) and improves evaluation speed due to cache efficiency.
Previously, when an error occurs inside a function call, the error position reported is the function call site. This makes it difficult to diagnose the actual location of the error within the function.
A new error variant EvalAltResult::ErrorInFunctionCall is added in this version.
It wraps the internal error returned by the called function, including the error position within the function.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →