rhai/doc/src/rust/modules/resolvers.md
2020-09-28 22:14:19 +08:00

4.1 KiB

Module Resolvers

{{#include ../../links.md}}

When encountering an [import] statement, Rhai attempts to resolve the module based on the path string.

Module Resolvers are service types that implement the [ModuleResolver][traits] trait.

Built-In Module Resolvers

There are a number of standard resolvers built into Rhai, the default being the FileModuleResolver which simply loads a script file based on the path (with .rhai extension attached) and execute it to form a module.

Built-in module resolvers are grouped under the rhai::module_resolvers module namespace.

FileModuleResolver (default)

The default module resolution service, not available for [no_std] or [WASM] builds. Loads a script file (based off the current directory) with .rhai extension.

All functions in the global namespace, plus all those defined in the same module, are merged into a unified namespace.

------------------
| my_module.rhai |
------------------

private fn inner_message() { "hello! from module!" }

fn greet(callback) { print(callback.call()); }

-------------
| main.rhai |
-------------

fn main_message() { "hi! from main!" }

import "my_module" as m;

m::greet(|| "hello, " + "world!");  // works - anonymous function in global

m::greet(|| inner_message());       // works - function in module

m::greet(|| main_message());        // works - function in global

The base directory can be changed via the FileModuleResolver::new_with_path constructor function.

FileModuleResolver::create_module loads a script file and returns a module.

GlobalFileModuleResolver

A simpler but more efficient version of FileModuleResolver, intended for short utility modules. Not available for [no_std] or [WASM] builds. Loads a script file (based off the current directory) with .rhai extension.

All functions are assumed independent and cannot cross-call each other. Functions are searched only in the global namespace.

------------------
| my_module.rhai |
------------------

private fn inner_message() { "hello! from module!" }

fn greet_inner() {
    print(inner_message());     // cross-calling a module function!
                                // there will be trouble because each function
                                // in the module is supposed to be independent
                                // of each other
}

fn greet() {
    print(main_message());      // function is searched in global namespace
}

-------------
| main.rhai |
-------------

fn main_message() { "hi! from main!" }

import "my_module" as m;

m::greet_inner();               // <- function not found: 'inner_message'

m::greet();                     // works because 'main_message' exists in
                                // the global namespace

The base directory can be changed via the FileModuleResolver::new_with_path constructor function.

GlobalFileModuleResolver::create_module loads a script file and returns a module.

StaticModuleResolver

Loads modules that are statically added. This can be used under [no_std].

Functions are searched in the global namespace by default.

use rhai::{Module, module_resolvers::StaticModuleResolver};

let module: Module = create_a_module();

let mut resolver = StaticModuleResolver::new();
resolver.insert("my_module", module);

ModuleResolversCollection

A collection of module resolvers. Modules will be resolved from each resolver in sequential order.

This is useful when multiple types of modules are needed simultaneously.

Set into Engine

An [Engine]'s module resolver is set via a call to Engine::set_module_resolver:

use rhai::module_resolvers::StaticModuleResolver;

// Create a module resolver
let resolver = StaticModuleResolver::new();

// Register functions into 'resolver'...

// Use the module resolver
engine.set_module_resolver(Some(resolver));

// Effectively disable 'import' statements by setting module resolver to 'None'
engine.set_module_resolver(None);