Skip to content

Commit

Permalink
feat: support quickjs_runtime backend ( #6 )
Browse files Browse the repository at this point in the history
  • Loading branch information
charlyisidore committed Jan 16, 2024
1 parent 1bc50c3 commit 7288d5b
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ thiserror = "1.0"
[target.'cfg(any(unix, all(windows, target_env = "gnu")))'.dependencies]
quick-js = { version = "0.4", features = ["patched"], optional = true }

# quickjs_runtime is available in unix
[target.'cfg(any(unix))'.dependencies]
quickjs_runtime = { version = "0.12.0", optional = true }

# duktape is available in unix and windows
[target.'cfg(any(unix, windows))'.dependencies]
ducc = { version = "0.1", optional = true }
Expand All @@ -36,6 +40,7 @@ wasm-bindgen-test = "0.3"
[features]
default = ["quick-js"]
quick-js = ["dep:quick-js"]
quickjs_runtime = ["dep:quickjs_runtime"]
duktape = ["dep:ducc"]
wasm-js = ["dep:wasm-bindgen", "dep:js-sys"]
wasm-js-test-in-browser = []
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ katex = "0.4"
This crate offers the following features:

* `quick-js`: Enable by default. Use [quick-js](https://crates.io/crates/quick-js) as the JS backend.
* `quickjs_runtime`: Use [quickjs_runtime](https://crates.io/crates/quickjs_runtime) as the JS backend. You need to disable the default features to enable this backend.
* `duktape`: Use [duktape](https://crates.io/crates/ducc) as the JS backend. You need to disable the default features to enable this backend.
* `wasm-js`: Use [wasm-bindgen](https://crates.io/crates/wasm-bindgen) and [js-sys](https://crates.io/crates/js-sys) as the JS backend. You need to disable the default features to enable this backend.

Expand Down
10 changes: 10 additions & 0 deletions src/js_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ cfg_if! {
compile_error!("quick-js backend is not support in the current build target.");
}
}
} else if #[cfg(feature = "quickjs_runtime")] {
cfg_if! {
if #[cfg(any(unix))] {
mod quickjs_runtime;

pub(crate) type Engine = self::quickjs_runtime::Engine;
} else {
compile_error!("quickjs_runtime backend is not support in the current build target.");
}
}
} else if #[cfg(feature = "duktape")] {
cfg_if! {
if #[cfg(any(unix, windows))] {
Expand Down
89 changes: 89 additions & 0 deletions src/js_engine/quickjs_runtime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//! JS Engine implemented by [quickjs_runtime](https://crates.io/crates/quickjs_runtime).
use std::collections::HashMap;

use quickjs_runtime::{
builder::QuickJsRuntimeBuilder,
facades::QuickJsRuntimeFacade,
jsutils::Script,
values::{JsValueConvertable, JsValueFacade},
};

use crate::{
error::{Error, Result},
js_engine::{JsEngine, JsValue},
};

/// quickjs_runtime Engine.
pub struct Engine(QuickJsRuntimeFacade);

impl JsEngine for Engine {
type JsValue<'a> = Value;

fn new() -> Result<Self> {
Ok(Self(QuickJsRuntimeBuilder::new().build()))
}

fn eval<'a>(&'a self, code: &str) -> Result<Self::JsValue<'a>> {
self.0
.eval_sync(None, Script::new("katex", code))
.map(Value)
.map_err(|e| Error::JsExecError(format!("{e}")))
}

fn call_function<'a>(
&'a self,
func_name: &str,
args: impl Iterator<Item = Self::JsValue<'a>>,
) -> Result<Self::JsValue<'a>> {
self.0
.invoke_function_sync(None, &[], func_name, args.map(|v| v.0).collect())
.map(Value)
.map_err(|e| Error::JsExecError(format!("{e}")))
}

fn create_bool_value(&self, input: bool) -> Result<Self::JsValue<'_>> {
Ok(input.into())
}

fn create_int_value(&self, input: i32) -> Result<Self::JsValue<'_>> {
Ok(input.into())
}

fn create_float_value(&self, input: f64) -> Result<Self::JsValue<'_>> {
Ok(input.into())
}

fn create_string_value(&self, input: String) -> Result<Self::JsValue<'_>> {
Ok(input.into())
}

fn create_object_value<'a>(
&'a self,
input: impl Iterator<Item = (String, Self::JsValue<'a>)>,
) -> Result<Self::JsValue<'a>> {
Ok(input
.map(|(k, v)| (k, v.0))
.collect::<HashMap<_, _>>()
.into())
}
}

/// quickjs_runtime Value.
#[derive(Debug)]
pub struct Value(JsValueFacade);

impl<'a> JsValue<'a> for Value {
fn into_string(self) -> Result<String> {
Ok(self.0.stringify())
}
}

impl<T> From<T> for Value
where
T: JsValueConvertable,
{
fn from(value: T) -> Self {
Self(value.to_js_value_facade())
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
//!
//! * `quick-js`: Enable by default. Use [quick-js](https://crates.io/crates/quick-js)
//! as the JS backend.
//! * `quickjs_runtime`: Use [quickjs_runtime](https://crates.io/crates/quickjs_runtime)
//! as the JS backend. You need to disable the default features to enable this backend.
//! * `duktape`: Use [duktape](https://crates.io/crates/ducc) as the JS backend.
//! You need to disable the default features to enable this backend.
//! * `wasm-js`: Use [wasm-bindgen](https://crates.io/crates/wasm-bindgen) and
Expand Down

0 comments on commit 7288d5b

Please sign in to comment.