docs.sheetjs.com/docz/docs/03-demos/42-engines/21-boa.md

171 lines
4.1 KiB
Markdown
Raw Normal View History

2023-05-22 08:06:09 +00:00
---
title: Rust + Boa
pagination_prev: demos/bigdata/index
pagination_next: solutions/input
---
import current from '/version.js';
import CodeBlock from '@theme/CodeBlock';
2023-08-31 22:09:08 +00:00
:::warning pass
2023-05-22 08:06:09 +00:00
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.
2023-09-22 06:32:55 +00:00
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
can be parsed and evaluated in a Boa context.
2023-05-22 08:06:09 +00:00
## 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);
2023-06-05 20:12:53 +00:00
match c.eval(src) {
2023-05-22 08:06:09 +00:00
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();
2023-06-05 20:12:53 +00:00
match c.eval(src) {
2023-05-22 08:06:09 +00:00
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
2023-06-05 20:12:53 +00:00
This demo was tested in the following deployments:
| Architecture | Date |
|:-------------|:-----------|
2023-08-31 22:09:08 +00:00
| `darwin-x64` | 2023-08-31 |
2023-07-06 07:21:41 +00:00
| `darwin-arm` | 2023-07-05 |
2023-09-25 07:30:54 +00:00
| `win10-x64` | 2023-08-31 |
2023-09-27 04:43:00 +00:00
| `win11-arm` | 2023-09-26 |
2023-10-12 08:39:38 +00:00
| `linux-x64` | 2023-10-11 |
2023-08-31 22:09:08 +00:00
| `linux-arm` | 2023-08-30 |
2023-05-22 08:06:09 +00:00
:::
1) Create a new project:
```bash
2023-07-06 07:21:41 +00:00
cargo new sheetjs-boa
cd sheetjs-boa
2023-05-22 08:06:09 +00:00
cargo run
```
2023-07-21 09:17:32 +00:00
2) Add the `boa_engine` crate:
2023-05-22 08:06:09 +00:00
```bash
2023-07-21 09:17:32 +00:00
cargo add boa_engine
2023-05-22 08:06:09 +00:00
```
2023-09-22 06:32:55 +00:00
3) Download the SheetJS Standalone script and move to the project directory:
<ul>
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
</ul>
2023-05-22 08:06:09 +00:00
<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
2023-08-31 22:09:08 +00:00
cargo run --release
2023-05-22 08:06:09 +00:00
```
After a short wait, the contents will be displayed in CSV form.
2023-08-31 22:09:08 +00:00
:::caution pass
The default debug build is not optimized and can elicit stack overflow errors.
It is strongly encouraged to use `--release` when possible.
:::