katex/js_engine/
quick_js.rs

1//! JS Engine implemented by [QuickJs](https://crates.io/crates/quick-js).
2
3use crate::{
4    error::{Error, Result},
5    js_engine::{JsEngine, JsValue},
6};
7use core::convert::TryInto;
8
9/// QuickJS Engine.
10pub struct Engine(quick_js::Context);
11
12impl JsEngine for Engine {
13    type JsValue<'a> = Value;
14
15    fn new() -> Result<Self> {
16        Ok(Self(quick_js::Context::new()?))
17    }
18
19    fn eval<'a>(&'a self, code: &str) -> Result<Self::JsValue<'a>> {
20        Ok(Value(self.0.eval(code)?))
21    }
22
23    fn call_function<'a>(
24        &'a self,
25        func_name: &str,
26        args: impl Iterator<Item = Self::JsValue<'a>>,
27    ) -> Result<Self::JsValue<'a>> {
28        Ok(Value(self.0.call_function(func_name, args.map(|v| v.0))?))
29    }
30
31    fn create_bool_value(&self, input: bool) -> Result<Self::JsValue<'_>> {
32        Ok(Value(quick_js::JsValue::Bool(input)))
33    }
34
35    fn create_int_value(&self, input: i32) -> Result<Self::JsValue<'_>> {
36        Ok(Value(quick_js::JsValue::Int(input)))
37    }
38
39    fn create_float_value(&self, input: f64) -> Result<Self::JsValue<'_>> {
40        Ok(Value(quick_js::JsValue::Float(input)))
41    }
42
43    fn create_string_value(&self, input: String) -> Result<Self::JsValue<'_>> {
44        Ok(Value(quick_js::JsValue::String(input)))
45    }
46
47    fn create_object_value<'a>(
48        &'a self,
49        input: impl Iterator<Item = (String, Self::JsValue<'a>)>,
50    ) -> Result<Self::JsValue<'a>> {
51        let obj = input.into_iter().map(|(k, v)| (k, v.0)).collect();
52        Ok(Value(quick_js::JsValue::Object(obj)))
53    }
54}
55
56/// QuickJS Value.
57#[derive(Debug)]
58pub struct Value(quick_js::JsValue);
59
60impl<'a> JsValue<'a> for Value {
61    fn into_string(self) -> Result<String> {
62        Ok(self.0.try_into()?)
63    }
64}
65
66impl From<quick_js::ContextError> for Error {
67    fn from(e: quick_js::ContextError) -> Self {
68        Self::JsInitError(format!("{e}"))
69    }
70}
71
72impl From<quick_js::ExecutionError> for Error {
73    fn from(e: quick_js::ExecutionError) -> Self {
74        Self::JsExecError(format!("{e}"))
75    }
76}
77
78impl From<quick_js::ValueError> for Error {
79    fn from(e: quick_js::ValueError) -> Self {
80        Self::JsValueError(format!("{e}"))
81    }
82}