1#![deny(unsafe_code)]
3
4use std::error::Error;
5
6pub use rquickjs;
8
9use rquickjs::{Context, Runtime, Value};
10
11pub struct Vm {
16 实例: Runtime,
18 语境: Context,
19}
20
21impl Vm {
22 pub fn new() -> Result<Self, Box<dyn Error>> {
24 let 实例 = Runtime::new()?;
25 let 语境 = Context::full(&实例)?;
26
27 Ok(Self { 实例, 语境 })
28 }
29
30 fn run_js<T, F>(&mut self, code: &str, f: F) -> Result<T, Box<dyn Error>>
32 where
33 F: FnOnce(Value) -> T,
34 {
35 self.语境.with(move |c| {
36 let r = c.eval(code)?;
37 Ok(f(r))
38 })
39 }
40
41 pub fn run_r<T, F>(&mut self, code: &str, f: F) -> Result<T, Box<dyn Error>>
43 where
44 F: FnOnce(Value) -> T,
45 {
46 self.run_js(code, f)
47 }
48
49 pub fn run(&mut self, code: &str) -> Result<(), Box<dyn Error>> {
51 self.run_js(code, |_| ())?;
52 Ok(())
53 }
54
55 pub fn gc(&self) {
57 self.实例.run_gc();
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn it_works() {
67 let mut vm = Vm::new().unwrap();
68 let r = vm.run_r("1 + 2", |r| r.as_int().unwrap()).unwrap();
69 assert_eq!(r, 3);
70 }
71}