feat: add wasm bindings
Some checks are pending
CI / Build and test : macOS-latest, msrv (push) Waiting to run
CI / Build and test : macOS-latest, nightly (push) Waiting to run
CI / Build and test : macOS-latest, stable (push) Waiting to run
CI / Build and test : ubuntu-latest, msrv (push) Waiting to run
CI / Build and test : ubuntu-latest, nightly (push) Waiting to run
CI / Build and test : ubuntu-latest, stable (push) Waiting to run
CI / Build and test : windows-latest, msrv (push) Waiting to run
CI / Build and test : windows-latest, nightly (push) Waiting to run
CI / Build and test : windows-latest, stable (push) Waiting to run
CI / Build and test --all-features: macOS-latest, msrv (push) Waiting to run
CI / Build and test --all-features: macOS-latest, nightly (push) Waiting to run
CI / Build and test --all-features: macOS-latest, stable (push) Waiting to run
CI / Build and test --all-features: ubuntu-latest, msrv (push) Waiting to run
CI / Build and test --all-features: ubuntu-latest, nightly (push) Waiting to run
CI / Build and test --all-features: ubuntu-latest, stable (push) Waiting to run
CI / Build and test --all-features: windows-latest, msrv (push) Waiting to run
CI / Build and test --all-features: windows-latest, nightly (push) Waiting to run
CI / Build and test --all-features: windows-latest, stable (push) Waiting to run
CI / Build and test --no-default-features: macOS-latest, msrv (push) Waiting to run
CI / Build and test --no-default-features: macOS-latest, nightly (push) Waiting to run
CI / Build and test --no-default-features: macOS-latest, stable (push) Waiting to run
CI / Build and test --no-default-features: ubuntu-latest, msrv (push) Waiting to run
CI / Build and test --no-default-features: ubuntu-latest, nightly (push) Waiting to run
CI / Build and test --no-default-features: ubuntu-latest, stable (push) Waiting to run
CI / Build and test --no-default-features: windows-latest, msrv (push) Waiting to run
CI / Build and test --no-default-features: windows-latest, nightly (push) Waiting to run
CI / Build and test --no-default-features: windows-latest, stable (push) Waiting to run
CI / cargo_fmt (push) Waiting to run
CI / check_minimal_versions (push) Waiting to run
CI / style_and_docs () (push) Waiting to run
CI / style_and_docs (--all-features) (push) Waiting to run
CI / style_and_docs (--no-default-features) (push) Waiting to run
CI / fuzz_read (push) Blocked by required conditions
CI / fuzz_read_with_no_features (push) Blocked by required conditions
CI / fuzz_write (push) Blocked by required conditions
CI / fuzz_write_with_no_features (push) Blocked by required conditions
DevSkim / DevSkim (push) Waiting to run
Release / Release-plz (push) Waiting to run
Some checks are pending
CI / Build and test : macOS-latest, msrv (push) Waiting to run
CI / Build and test : macOS-latest, nightly (push) Waiting to run
CI / Build and test : macOS-latest, stable (push) Waiting to run
CI / Build and test : ubuntu-latest, msrv (push) Waiting to run
CI / Build and test : ubuntu-latest, nightly (push) Waiting to run
CI / Build and test : ubuntu-latest, stable (push) Waiting to run
CI / Build and test : windows-latest, msrv (push) Waiting to run
CI / Build and test : windows-latest, nightly (push) Waiting to run
CI / Build and test : windows-latest, stable (push) Waiting to run
CI / Build and test --all-features: macOS-latest, msrv (push) Waiting to run
CI / Build and test --all-features: macOS-latest, nightly (push) Waiting to run
CI / Build and test --all-features: macOS-latest, stable (push) Waiting to run
CI / Build and test --all-features: ubuntu-latest, msrv (push) Waiting to run
CI / Build and test --all-features: ubuntu-latest, nightly (push) Waiting to run
CI / Build and test --all-features: ubuntu-latest, stable (push) Waiting to run
CI / Build and test --all-features: windows-latest, msrv (push) Waiting to run
CI / Build and test --all-features: windows-latest, nightly (push) Waiting to run
CI / Build and test --all-features: windows-latest, stable (push) Waiting to run
CI / Build and test --no-default-features: macOS-latest, msrv (push) Waiting to run
CI / Build and test --no-default-features: macOS-latest, nightly (push) Waiting to run
CI / Build and test --no-default-features: macOS-latest, stable (push) Waiting to run
CI / Build and test --no-default-features: ubuntu-latest, msrv (push) Waiting to run
CI / Build and test --no-default-features: ubuntu-latest, nightly (push) Waiting to run
CI / Build and test --no-default-features: ubuntu-latest, stable (push) Waiting to run
CI / Build and test --no-default-features: windows-latest, msrv (push) Waiting to run
CI / Build and test --no-default-features: windows-latest, nightly (push) Waiting to run
CI / Build and test --no-default-features: windows-latest, stable (push) Waiting to run
CI / cargo_fmt (push) Waiting to run
CI / check_minimal_versions (push) Waiting to run
CI / style_and_docs () (push) Waiting to run
CI / style_and_docs (--all-features) (push) Waiting to run
CI / style_and_docs (--no-default-features) (push) Waiting to run
CI / fuzz_read (push) Blocked by required conditions
CI / fuzz_read_with_no_features (push) Blocked by required conditions
CI / fuzz_write (push) Blocked by required conditions
CI / fuzz_write_with_no_features (push) Blocked by required conditions
DevSkim / DevSkim (push) Waiting to run
Release / Release-plz (push) Waiting to run
This commit is contained in:
parent
e074e09b83
commit
473b156e1f
7 changed files with 115 additions and 2 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -4,3 +4,8 @@ target
|
|||
\.idea/
|
||||
/fuzz_read/out/
|
||||
/fuzz_write/out/
|
||||
|
||||
## wasm start ##
|
||||
pkg/
|
||||
extracted/
|
||||
## wasm end ##
|
||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "wasynth"]
|
||||
path = wasynth
|
||||
url = https://github.com/Rerumu/Wasynth.git
|
16
Cargo.toml
16
Cargo.toml
|
@ -18,6 +18,9 @@ edition = "2021"
|
|||
exclude = ["tests/**", "examples/**", ".github/**", "fuzz_read/**", "fuzz_write/**"]
|
||||
build = "src/build.rs"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
@ -26,8 +29,16 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||
time = { version = "0.3.1", default-features = false }
|
||||
|
||||
[dependencies]
|
||||
## wasm dependencies start ##
|
||||
wasm-bindgen = { version = "0.2" }
|
||||
js-sys = { version = "0.3" }
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
bzip2 = { path = "./bzip2-rs", optional = true, default-features = false, features = ["libbz2-rs-sys"] }
|
||||
zstd = { version = "0.13", optional = true, default-features = false, features = ["wasm"] }
|
||||
## wasm dependencies end ##
|
||||
|
||||
aes = { version = "0.8", optional = true }
|
||||
bzip2 = { version = "0.4.3", optional = true }
|
||||
# bzip2 = { version = "0.4.3", optional = true }
|
||||
chrono = { version = "0.4", optional = true }
|
||||
constant_time_eq = { version = "0.3", optional = true }
|
||||
crc32fast = "1.4"
|
||||
|
@ -44,7 +55,7 @@ time = { workspace = true, optional = true, features = [
|
|||
"std",
|
||||
] }
|
||||
zeroize = { version = "1.8", optional = true, features = ["zeroize_derive"] }
|
||||
zstd = { version = "0.13", optional = true, default-features = false }
|
||||
# zstd = { version = "0.13", optional = true, default-features = false }
|
||||
zopfli = { version = "0.8", optional = true }
|
||||
deflate64 = { version = "0.1.9", optional = true }
|
||||
lzma-rs = { version = "0.3", default-features = false, optional = true }
|
||||
|
@ -101,3 +112,4 @@ harness = false
|
|||
[[bench]]
|
||||
name = "merge_archive"
|
||||
harness = false
|
||||
|
||||
|
|
1
bzip2-rs
Submodule
1
bzip2-rs
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 15258feb0cdc1114d6fc6b936254c4f4e1d5730c
|
72
src/lib.rs
72
src/lib.rs
|
@ -31,6 +31,7 @@
|
|||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![warn(missing_docs)]
|
||||
#![allow(unexpected_cfgs)] // Needed for cfg(fuzzing) on nightly as of 2024-05-06
|
||||
|
||||
pub use crate::compression::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS};
|
||||
pub use crate::read::HasZipMetadata;
|
||||
pub use crate::read::ZipArchive;
|
||||
|
@ -67,3 +68,74 @@ zip = \"="]
|
|||
#[doc = "\"\n\
|
||||
```"]
|
||||
pub mod unstable;
|
||||
|
||||
// ====== wasm start ====== //
|
||||
|
||||
use std::io::{Cursor, Read};
|
||||
|
||||
use result::{ZipResult, ZipError};
|
||||
|
||||
use wasm_bindgen::{prelude::*, JsValue};
|
||||
use js_sys::{Array, Object, Error, Reflect::set};
|
||||
|
||||
//
|
||||
// Utilities
|
||||
//
|
||||
|
||||
impl From<ZipError> for JsValue {
|
||||
fn from(err: ZipError) -> JsValue {
|
||||
match err {
|
||||
ZipError::Io(e) => JsValue::from(Error::new(&format!("IO Error: {}", e))),
|
||||
ZipError::InvalidArchive(msg) => JsValue::from(Error::new(&format!("Invalid Archive: {}", msg))),
|
||||
ZipError::UnsupportedArchive(msg) => JsValue::from(Error::new(&format!("Unsupported Archive: {}", msg))),
|
||||
ZipError::FileNotFound => JsValue::from(Error::new("File Not Found")),
|
||||
ZipError::InvalidPassword => JsValue::from(Error::new("Invalid Password")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Converts a Rust `Vec` to a JS Array.
|
||||
fn vec_to_js_array<T: Into<JsValue>>(vec: Vec<T>) -> Array {
|
||||
let js_array = Array::new();
|
||||
for item in vec {
|
||||
js_array.push(&item.into());
|
||||
}
|
||||
|
||||
js_array
|
||||
}
|
||||
|
||||
//
|
||||
// Exports
|
||||
//
|
||||
|
||||
/// Unzips a file provided as a JS array, returning a mapping of filenames to decompressed
|
||||
/// contents.
|
||||
#[wasm_bindgen]
|
||||
pub fn unzip(bytes: &[u8]) -> ZipResult<JsValue> {
|
||||
// TODO: Accept Uint8Array instead of array
|
||||
|
||||
let cursor = Cursor::new(bytes);
|
||||
let mut archive = ZipArchive::new(cursor)?;
|
||||
let extracted_files = Object::new();
|
||||
|
||||
for i in 0..archive.len() {
|
||||
let mut file = archive.by_index(i)?;
|
||||
let file_name = file.name().to_string();
|
||||
|
||||
// Read the file contents into a Vec<u8>
|
||||
let mut contents = Vec::new();
|
||||
file.read_to_end(&mut contents)?;
|
||||
|
||||
// Convert to JS values and insert into object
|
||||
let js_file_name = JsValue::from(file_name);
|
||||
let js_contents = vec_to_js_array(contents);
|
||||
|
||||
set(&extracted_files, &js_file_name, &js_contents).unwrap();
|
||||
}
|
||||
|
||||
Ok(JsValue::from(&extracted_files))
|
||||
}
|
||||
|
||||
|
||||
// ====== wasm end ====== //
|
||||
|
|
19
test.ts
Normal file
19
test.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import * as path from "jsr:@std/path";
|
||||
import { ensureDir } from "jsr:@std/fs";
|
||||
import { unzip } from "./pkg/zip.js";
|
||||
|
||||
const EXTRACTED_DIR = "./extracted";
|
||||
await ensureDir(EXTRACTED_DIR);
|
||||
|
||||
const TARGET_PATH = Deno.args[0];
|
||||
if (!TARGET_PATH) {
|
||||
console.error("usage: test.js <path>");
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
const zipFile = Deno.readFileSync(TARGET_PATH);
|
||||
for (const [file, contents] of Object.entries(unzip([...zipFile]))) {
|
||||
// TODO: handle directories & more in the future
|
||||
const contentBytes = new TextEncoder().encode(contents);
|
||||
Deno.writeFileSync(path.join(EXTRACTED_DIR, file), contentBytes);
|
||||
}
|
1
wasynth
Submodule
1
wasynth
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 27f34987341ec1837d3ff911f3e583647920af16
|
Loading…
Add table
Reference in a new issue