Add closure test.
This commit is contained in:
parent
1bfedf516d
commit
3e4da98703
@ -375,3 +375,62 @@ fn test_closures_external() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
fn test_closures_callback() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
type SingleNode = Rc<dyn Node>;
|
||||||
|
|
||||||
|
trait Node {
|
||||||
|
fn run(&self, x: INT) -> INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PhaserNode {
|
||||||
|
func: Box<dyn Fn(INT) -> INT>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node for PhaserNode {
|
||||||
|
fn run(&self, x: INT) -> INT {
|
||||||
|
(self.func)(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn phaser(callback: impl Fn(INT) -> INT + 'static) -> impl Node {
|
||||||
|
PhaserNode {
|
||||||
|
func: Box::new(callback),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
|
let ast = Rc::new(engine.compile(
|
||||||
|
"
|
||||||
|
const FACTOR = 2;
|
||||||
|
phaser(|x| x * FACTOR)
|
||||||
|
",
|
||||||
|
)?);
|
||||||
|
|
||||||
|
let shared_engine = Rc::new(RefCell::new(Engine::new_raw()));
|
||||||
|
let engine2 = shared_engine.clone();
|
||||||
|
let ast2 = ast.clone();
|
||||||
|
|
||||||
|
engine.register_fn("phaser", move |fp: FnPtr| {
|
||||||
|
let engine = engine2.clone();
|
||||||
|
let ast = ast2.clone();
|
||||||
|
|
||||||
|
let callback = Box::new(move |x: INT| fp.call(&engine.borrow(), &ast, (x,)).unwrap());
|
||||||
|
|
||||||
|
Rc::new(phaser(callback)) as SingleNode
|
||||||
|
});
|
||||||
|
|
||||||
|
*shared_engine.borrow_mut() = engine;
|
||||||
|
|
||||||
|
let cb = shared_engine.borrow().eval_ast::<SingleNode>(&ast)?;
|
||||||
|
|
||||||
|
assert_eq!(cb.run(21), 42);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user