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
82
83
84
85
86
87
88
89
90
///
/// This example is meant to demonstrate sending and receiving custom types
/// between JS and rust
///
use rustyscript::{module, Error, Module, ModuleWrapper};
use serde::{Deserialize, Serialize};
// Modules can be defined statically using this macro!
static MY_MODULE: Module = module!(
"custom_types.js",
"
// Mapping the enum types over like this isn't strictly needed
// But it does help prevent bugs!
const BridgeCrossingResults = {
Permitted: 'Permitted',
Denied: 'Denied'
};
const Quests = {
HolyGrail: 'HolyGrail',
Groceries: 'Groceries',
Sandwich: 'Sandwich',
}
export function checkAttempt(attempt) {
if (attempt.quest == Quests.HolyGrail) {
return BridgeCrossingResults.Permitted;
} else {
return BridgeCrossingResults.Denied;
}
}
"
);
/// This enum will be used by both rust and JS
/// It will be returned by JS, and thus needs Deserialize
/// The other 2 traits are only for the assert_eq! macro below
#[derive(Deserialize, PartialEq, Debug)]
enum BridgeCrossingResult {
Permitted,
Denied,
}
/// This enum will be used by both rust and JS
/// Since it is being send to JS, it needs Serialize
#[derive(Serialize)]
enum Quest {
HolyGrail,
Groceries,
}
/// This type will be sent into the JS module
/// Since it is being send to JS, it needs Serialize
#[derive(Serialize)]
struct BridgeCrossingAttempt {
name: String,
quest: Quest,
favourite_colour: String,
}
fn main() -> Result<(), Error> {
// We only have one source file, so it is simpler here to just use this wrapper type
// As opposed to building a complete runtime.
let mut module = ModuleWrapper::new_from_module(&MY_MODULE, Default::default())?;
// Although we can use json_args!() to call a function with primitives as arguments
// More complicated types must use `Runtime::arg`
let result: BridgeCrossingResult = module.call(
"checkAttempt",
&BridgeCrossingAttempt {
name: "Lancelot".to_string(),
quest: Quest::Groceries,
favourite_colour: "blue".to_string(),
},
)?;
assert_eq!(result, BridgeCrossingResult::Denied);
// Let us try again with different values...
let result: BridgeCrossingResult = module.call(
"checkAttempt",
&BridgeCrossingAttempt {
name: "Lancelot".to_string(),
quest: Quest::HolyGrail,
favourite_colour: "blue".to_string(),
},
)?;
assert_eq!(result, BridgeCrossingResult::Permitted);
Ok(())
}