152 lines
3.6 KiB
Markdown
152 lines
3.6 KiB
Markdown
|
---
|
||
|
title: Rust + Boa
|
||
|
pagination_prev: demos/bigdata/index
|
||
|
pagination_next: solutions/input
|
||
|
---
|
||
|
|
||
|
import current from '/version.js';
|
||
|
import CodeBlock from '@theme/CodeBlock';
|
||
|
|
||
|
:::warning
|
||
|
|
||
|
In a production application, it is strongly recommended to use a binding for a
|
||
|
more performant engine like [`v8`](/docs/demos/engines/v8#rust)
|
||
|
|
||
|
:::
|
||
|
|
||
|
Boa is a pure-Rust JavaScript engine.
|
||
|
|
||
|
The [Standalone scripts](/docs/getting-started/installation/standalone) can be
|
||
|
parsed and evaluated in a Boa context.
|
||
|
|
||
|
|
||
|
## Integration Details
|
||
|
|
||
|
_Initialize Engine_
|
||
|
|
||
|
A JS context can be constructed in one line:
|
||
|
|
||
|
```rust
|
||
|
use boa_engine::Context;
|
||
|
|
||
|
/* initialize */
|
||
|
let context = &mut Context::default();
|
||
|
```
|
||
|
|
||
|
The following helper function evaluates strings as JS code:
|
||
|
|
||
|
```rust
|
||
|
use std::string::String;
|
||
|
use boa_engine::{Context, Source, JsError};
|
||
|
|
||
|
/* simple wrapper to evaluate code snippets */
|
||
|
fn eval_code(c: &mut Context, code: &str) -> Result<String, JsError> {
|
||
|
let src = Source::from_bytes(code);
|
||
|
match c.eval_script(src) {
|
||
|
Ok(res) => { return Ok(res.to_string(c).unwrap().to_std_string_escaped()); }
|
||
|
Err(e) => { return Err(e); }
|
||
|
};
|
||
|
}
|
||
|
```
|
||
|
|
||
|
_Load SheetJS Scripts_
|
||
|
|
||
|
Boa provides a special helper to read source code from a path:
|
||
|
|
||
|
```rust
|
||
|
use std::path::Path;
|
||
|
use std::string::String;
|
||
|
use boa_engine::{Context, Source, JsError};
|
||
|
|
||
|
/* simple wrapper to evaluate an entire script file */
|
||
|
fn eval_file(c: &mut Context, path: &str) -> Result<String, JsError> {
|
||
|
let src = Source::from_filepath(Path::new(path)).unwrap();
|
||
|
match c.eval_script(src) {
|
||
|
Ok(res) => { return Ok(res.to_string(c).unwrap().to_std_string_escaped()); }
|
||
|
Err(e) => { return Err(e); }
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// ...
|
||
|
/* load library */
|
||
|
match eval_file(context, "./xlsx.full.min.js") {
|
||
|
Ok(_res) => {}
|
||
|
Err(e) => { return eprintln!("Uncaught {e}"); }
|
||
|
}
|
||
|
```
|
||
|
|
||
|
To confirm the library is loaded, `XLSX.version` can be inspected:
|
||
|
|
||
|
```rust
|
||
|
/* get version string */
|
||
|
match eval_code(context, "XLSX.version") {
|
||
|
Ok(res) => { println!( "SheetJS library version {}", res); }
|
||
|
Err(e) => { return eprintln!("Uncaught {e}"); }
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Reading Files
|
||
|
|
||
|
Boa supports `ArrayBuffer` natively. This snippet reads data from a file into
|
||
|
`Vec<u8>` and stores the data as an `ArrayBuffer` in global scope:
|
||
|
|
||
|
```rust
|
||
|
/* read file */
|
||
|
let data: Vec<u8> = fs::read("pres.xlsx").unwrap();
|
||
|
let array: JsArrayBuffer = JsArrayBuffer::from_byte_block(data, context).unwrap();
|
||
|
let attrs = Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE;
|
||
|
context.register_global_property("buf", array, attrs);
|
||
|
|
||
|
/* parse with SheetJS */
|
||
|
match eval_code(context, "void (globalThis.wb = XLSX.read(buf))") {
|
||
|
Ok(_res) => { }
|
||
|
Err(e) => { return eprintln!("Uncaught {e}"); }
|
||
|
}
|
||
|
```
|
||
|
|
||
|
`wb` will be a variable in the JS environment that can be inspected using the
|
||
|
various SheetJS API functions.
|
||
|
|
||
|
## Complete Example
|
||
|
|
||
|
:::note
|
||
|
|
||
|
This demo was tested on 2023 May 22
|
||
|
|
||
|
:::
|
||
|
|
||
|
1) Create a new project:
|
||
|
|
||
|
```bash
|
||
|
cargo new sheetjs-rs
|
||
|
cd sheetjs-rs
|
||
|
cargo run
|
||
|
```
|
||
|
|
||
|
2) Add the `boa` crate from the Git repository:
|
||
|
|
||
|
```bash
|
||
|
cargo add --git https://github.com/boa-dev/boa boa_engine
|
||
|
```
|
||
|
|
||
|
3) Download the [Standalone build](/docs/getting-started/installation/standalone):
|
||
|
|
||
|
<CodeBlock language="bash">{`\
|
||
|
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
|
||
|
</CodeBlock>
|
||
|
|
||
|
4) Download [`main.rs`](pathname:///boa/main.rs) and replace `src/main.rs`:
|
||
|
|
||
|
```bash
|
||
|
curl -L -o src/main.rs https://docs.sheetjs.com/boa/main.rs
|
||
|
```
|
||
|
|
||
|
5) Download [the test file](https://sheetjs.com/pres.xlsx) and run:
|
||
|
|
||
|
```bash
|
||
|
curl -LO https://sheetjs.com/pres.xlsx
|
||
|
cargo run
|
||
|
```
|
||
|
|
||
|
After a short wait, the contents will be displayed in CSV form.
|