pmse_jsb/
lib.rs

1//! pmse-jsb
2#![deny(unsafe_code)]
3
4use std::error::Error;
5
6// re-export
7pub use rquickjs;
8
9use rquickjs::{Context, Runtime, Value};
10
11//mod err;
12//pub use err::E;
13
14/// 用来运行 JS 代码的虚拟机 (QuickJS Runtime)
15pub struct Vm {
16    // no Debug
17    实例: Runtime,
18    语境: Context,
19}
20
21impl Vm {
22    /// 创建新实例
23    pub fn new() -> Result<Self, Box<dyn Error>> {
24        let 实例 = Runtime::new()?;
25        let 语境 = Context::full(&实例)?;
26
27        Ok(Self { 实例, 语境 })
28    }
29
30    /// (内部) 运行一段 JS 代码, 返回结果.
31    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    /// (封装) 运行一段 JS 代码, 返回结果.
42    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    /// (封装) 运行一段 JS 代码, 无需结果.
50    pub fn run(&mut self, code: &str) -> Result<(), Box<dyn Error>> {
51        self.run_js(code, |_| ())?;
52        Ok(())
53    }
54
55    /// 手动运行 GC (垃圾收集)
56    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}