47 lines
1.6 KiB
Markdown
47 lines
1.6 KiB
Markdown
Create a Rust Closure from a Rhai Function
|
|
==========================================
|
|
|
|
{{#include ../links.md}}
|
|
|
|
```admonish tip.side "Tip"
|
|
|
|
Very useful as callback functions!
|
|
```
|
|
|
|
It is possible to further encapsulate a script in Rust such that it becomes a normal Rust closure.
|
|
|
|
Creating them is accomplished via the `Func` trait which contains `create_from_script`
|
|
(as well as its companion method `create_from_ast`).
|
|
|
|
```rust
|
|
use rhai::{Engine, Func}; // use 'Func' for 'create_from_script'
|
|
|
|
let engine = Engine::new(); // create a new 'Engine' just for this
|
|
|
|
let script = "fn calc(x, y) { x + y.len < 42 }";
|
|
|
|
// Func takes two type parameters:
|
|
// 1) a tuple made up of the types of the script function's parameters
|
|
// 2) the return type of the script function
|
|
//
|
|
// 'func' will have type Box<dyn Fn(i64, &str) -> Result<bool, Box<EvalAltResult>>> and is callable!
|
|
let func = Func::<(i64, &str), bool>::create_from_script(
|
|
// ^^^^^^^^^^^ function parameter types in tuple
|
|
|
|
engine, // the 'Engine' is consumed into the closure
|
|
script, // the script, notice number of parameters must match
|
|
"calc" // the entry-point function name
|
|
)?;
|
|
|
|
func(123, "hello")? == false; // call the closure
|
|
|
|
schedule_callback(func); // pass it as a callback to another function
|
|
|
|
// Although there is nothing you can't do by manually writing out the closure yourself...
|
|
let engine = Engine::new();
|
|
let ast = engine.compile(script)?;
|
|
schedule_callback(Box::new(move |x: i64, y: String| {
|
|
engine.call_fn::<bool>(&mut Scope::new(), &ast, "calc", (x, y))
|
|
}));
|
|
```
|