-
Notifications
You must be signed in to change notification settings - Fork 182
/
Copy pathside_effects.rs
81 lines (66 loc) · 2.16 KB
/
side_effects.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
///! This test simulates an external command object that is driven by a script.
use rhai::{Engine, Scope, INT};
use std::sync::{Arc, Mutex, RwLock};
/// Simulate a command object.
struct Command {
/// Simulate an external state.
state: INT,
}
impl Command {
/// Do some action.
pub fn action(&mut self, val: INT) {
self.state = val;
}
/// Get current value.
pub fn get(&self) -> INT {
self.state
}
}
#[allow(clippy::upper_case_acronyms)]
type API = Arc<Mutex<Command>>;
#[cfg(not(feature = "no_object"))]
#[test]
fn test_side_effects_command() {
let mut engine = Engine::new();
let mut scope = Scope::new();
// Create the command object with initial state, handled by an `Arc`.
let command = Arc::new(Mutex::new(Command { state: 12 }));
assert_eq!(command.lock().unwrap().get(), 12);
// Create the API object.
let api = command.clone(); // Notice this clones the `Arc` only
// Make the API object a singleton in the script environment.
scope.push_constant("Command", api);
// Register type.
engine.register_type_with_name::<API>("CommandType");
engine.register_fn("action", |api: &mut API, x: INT| {
let mut command = api.lock().unwrap();
let val = command.get();
command.action(val + x);
});
engine.register_get("value", |command: &mut API| command.lock().unwrap().get());
assert_eq!(
engine
.eval_with_scope::<INT>(
&mut scope,
"
// Drive the command object via the wrapper
Command.action(30);
Command.value
"
)
.unwrap(),
42
);
// Make sure the actions are properly performed
assert_eq!(command.lock().unwrap().get(), 42);
}
#[test]
fn test_side_effects_print() {
let result = Arc::new(RwLock::new(String::new()));
let mut engine = Engine::new();
// Override action of 'print' function
let logger = result.clone();
engine.on_print(move |s| logger.write().unwrap().push_str(s));
engine.run("print(40 + 2);").unwrap();
assert_eq!(*result.read().unwrap(), "42");
}