Working with Any Rust Type

Tip: Shared types

The only requirement of a type to work with Rhai is Clone.

Therefore, it is extremely easy to use Rhai with data types such as Rc<...>, Arc<...>, Rc<RefCell<...>>, Arc<Mutex<...>> etc.

Under sync

If the sync feature is used, a custom type must also be Send + Sync.

Rhai works seamlessly with any Rust type, as long as it implements Clone as this allows the Engine to pass by value.

A type that is not one of the standard types is termed a “custom type”.

Custom types can have the following:

Free Typing

Why “Custom”?

Rhai internally supports a number of standard data types (see this list).

Any type outside of the list is considered custom.

Custom types are slower

Custom types run slower than built-in types due to an additional level of indirection, but for all other purposes there is no difference.

Rhai works seamlessly with any Rust type.

A custom type is stored in Rhai as a Rust trait object (specifically, a dyn rhai::Variant), with no restrictions other than being Clone (plus Send + Sync under the sync feature).

The type literally does not have any prerequisite other than being Clone.

It does not need to implement any other trait or use any custom #[derive].

This allows Rhai to be integrated into an existing Rust code base with as little plumbing as possible, usually silently and seamlessly.

External types that are not defined within the same crate (and thus cannot implement special Rhai traits or use special #[derive]) can also be used easily with Rhai.

Support for custom types can be turned off via the no_object feature.

Register API

For Rhai scripts to interact with the custom type, and API must be registered for it with the Engine.

The API can consist of functions, methods, property getters/setters, indexers, iterators etc.

There are three ways to register an API for a custom type.

1. Auto-Generate API

If you have complete control of the type, then this is the easiest way.

The #[derive(CustomType)] macro can be used to automatically generate an API for a custom type via the CustomType trait.

2. Custom Type Builder

For types in the same crate that you do not control, each function, method, property getter/setter, indexer and iterator can be registered manually, as a single package, via the CustomType trait using the Custom Type Builder.

3. Manual Registration

For external types that cannot implement the CustomType trait due to Rust’s orphan rule, each function, method, property getter/setter, indexer and iterator must be registered manually with the Engine.