# js-sandbox-ios [crates.io](https://crates.io/crates/js-sandbox) [docs.rs](https://docs.rs/js-sandbox) `js-sandbox` is a Rust library for executing JavaScript code from Rust in a secure sandbox. It is based on the [Deno] project and uses [serde_json] for serialization. This library's primary focus is **embedding JS as a scripting language into Rust**. It does not provide all possible integrations between the two languages, and is not tailored to JS's biggest domain as a client/server side language of the web. Instead, `js-sandbox` focuses on calling standalone JS code from Rust, and tries to remain as simple as possible in doing so. The typical use case is a core Rust application that integrates with scripts from external users, for example a plugin system or a game that runs external mods. This library is in early development, with a basic but powerful API. The API may still evolve considerably. ## Examples ### Print from JavaScript The _Hello World_ example -- print something using JavaScript -- is one line, as it should be: ```rust fn main() { js_sandbox_ios::eval_json("console.log('Hello Rust from JS')").expect("JS runs"); } ``` ### Call a JS function A very basic application calls a JavaScript function `sub()` from Rust. It passes an argument and accepts a return value, both serialized via JSON: ```rust use js_sandbox_ios::{Script, AnyError}; fn main() -> Result<(), AnyError> { let js_code = "function sub(a, b) { return a - b; }"; let mut script = Script::from_string(js_code)?; let result: i32 = script.call("sub", (7, 5))?; assert_eq!(result, 2); Ok(()) } ``` An example that serializes a JSON object (Rust -> JS) and formats a string (JS -> Rust): ```rust use js_sandbox_ios::{Script, AnyError}; use serde::Serialize; #[derive(Serialize)] struct Person { name: String, age: u8, } fn main() -> Result<(), AnyError> { let src = r#" function toString(person) { return "A person named " + person.name + " of age " + person.age; }"#; let mut script = Script::from_string(src)?; let person = Person { name: "Roger".to_string(), age: 42 }; let result: String = script.call("toString", (person,))?; assert_eq!(result, "A person named Roger of age 42"); Ok(()) } ``` ### Load JS file JavaScript files can be loaded from any `Path` at runtime (e.g. 3rd party mods). If you want to statically embed UTF-8 encoded files in the Rust binary, you can alternatively use the [`std::include_str`](https://doc.rust-lang.org/std/macro.include_str.html) macro. ```rust use js_sandbox_ios::Script; fn main() { // (1) at runtime: let mut script = Script::from_file("script.js").expect("load + init succeeds"); // (2) at compile time: let code: &'static str = include_str!("script.js"); let mut script = Script::from_string(code).expect("init succeeds"); // use script as usual } ``` ### Maintain state in JavaScript It is possible to initialize a stateful JS script, and then use functions to modify that state over time. This example appends a string in two calls, and then gets the result in a third call: ```rust use js_sandbox_ios::{Script, AnyError}; fn main() -> Result<(), AnyError> { let src = r#" var total = ''; function append(str) { total += str; } function get() { return total; }"#; let mut script = Script::from_string(src)?; let _: () = script.call("append", ("hello",))?; let _: () = script.call("append", (" world",))?; let result: String = script.call("get", ())?; assert_eq!(result, "hello world"); Ok(()) } ``` ### Call a script with timeout The JS code may contain long- or forever-running loops that block Rust code. It is possible to set a timeout, after which JavaScript execution is aborted. ```rust use js_sandbox_ios::{Script, JsError}; fn main() -> Result<(), JsError> { use std::time::Duration; let js_code = "function run_forever() { for(;;) {} }"; let mut script = Script::from_string(js_code)? .with_timeout(Duration::from_millis(1000)); let result: Result = script.call("run_forever", ()); assert_eq!( result.unwrap_err().to_string(), "Uncaught Error: execution terminated".to_string() ); Ok(()) } ``` [Deno]: https://deno.land [serde_json]: https://docs.serde.rs/serde_json License: Zlib