Skip to content

Commit eaf5578

Browse files
authored
Merge pull request #3 from maxjvh/main
2 parents af42f49 + 9ba5be1 commit eaf5578

File tree

3 files changed

+71
-6
lines changed

3 files changed

+71
-6
lines changed

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ lto = true
1818
opt-level = 's'
1919

2020
[dependencies]
21-
wasm-bindgen = "0.2"
21+
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
2222
brotli = "3.3"
2323
wee_alloc = { version = "0.4", optional = true }
24-
console_error_panic_hook = { version = "0.1", optional = true }
24+
console_error_panic_hook = { version = "0.1", optional = true }
25+
serde = { version = "1.0", features = ["derive"] }
26+
serde_json = { version = "1.0" }

src/lib.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use brotli;
22
use wasm_bindgen::prelude::*;
3+
use serde::{Serialize, Deserialize};
34

45
#[cfg(feature = "wee_alloc")]
56
#[global_allocator]
@@ -10,11 +11,40 @@ fn set_panic_hook() {
1011
console_error_panic_hook::set_once();
1112
}
1213

13-
#[wasm_bindgen(js_name = compress)]
14-
pub fn compress(buf: Box<[u8]>) -> Result<Box<[u8]>, JsValue> {
14+
#[wasm_bindgen(typescript_custom_section)]
15+
const TS_APPEND_CONTENT: &'static str = r#"
16+
17+
type Options = {
18+
quality?: number
19+
};
20+
21+
export function compress(buf: Uint8Array, options?: Options): Uint8Array;
22+
"#;
23+
24+
#[derive(Serialize, Deserialize)]
25+
pub struct Options {
26+
#[serde(default = "default_quality")]
27+
pub quality: i32
28+
}
29+
30+
fn default_quality() -> i32 { 11 }
31+
32+
#[wasm_bindgen(js_name = compress, skip_typescript)]
33+
pub fn compress(buf: Box<[u8]>, raw_options: &JsValue) -> Result<Box<[u8]>, JsValue> {
1534
set_panic_hook();
35+
36+
let options: Options;
37+
if raw_options.is_undefined() {
38+
options = serde_json::from_str("{}").unwrap();
39+
} else if raw_options.is_object() {
40+
options = raw_options.into_serde().unwrap();
41+
} else {
42+
return Err(JsValue::from_str("Options is not an object"));
43+
}
44+
1645
let mut out = Vec::<u8>::new();
17-
let params = brotli::enc::BrotliEncoderParams::default();
46+
let mut params = brotli::enc::BrotliEncoderParams::default();
47+
params.quality = options.quality;
1848

1949
match brotli::BrotliCompress(&mut buf.as_ref(), &mut out, &params) {
2050
Ok(_) => (),

test/brotli.spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,38 @@ describe("Brotli-wasm", () => {
1414
expect(Buffer.from(result).toString('base64')).to.equal('Gw4A+KWpyubolCCjVAjmxJ4D');
1515
});
1616

17+
it("can compress data with a different quality setting", () => {
18+
const input = Buffer.from("Test input data");
19+
const result = brotli.compress(input, { quality: 1 });
20+
expect(Buffer.from(result).toString('base64')).to.equal('CweAVGVzdCBpbnB1dCBkYXRhAw==');
21+
});
22+
1723
it("can decompress data", () => {
1824
// Generated with: echo -n '$CONTENT' | brotli --stdout - | base64
1925
const input = Buffer.from('GxoAABypU587dC0k9ianQOgqjS32iUTcCA==', 'base64');
2026
const result = brotli.decompress(input);
2127
expect(Buffer.from(result).toString('utf8')).to.equal('Brotli brotli brotli brotli');
2228
});
2329

30+
it("cleanly fails when options is something other than an object", () => {
31+
const input = Buffer.from("Test input data");
32+
expect(() =>
33+
brotli.compress(input, "this should not be a string" as any)
34+
).to.throw('Options is not an object');
35+
});
36+
37+
it("does not fail when options contain unknown properties", () => {
38+
const input = Buffer.from("Test input data");
39+
const result = brotli.compress(input, { someRandomKey: 1, quality: 5 } as any);
40+
expect(Buffer.from(result).toString('base64')).to.equal('CweAVGVzdCBpbnB1dCBkYXRhAw==');
41+
});
42+
43+
it("does not fail when compressing with an illegal quality value", () => {
44+
const input = Buffer.from("Test input data");
45+
const result = brotli.compress(input, { quality: 12 });
46+
expect(Buffer.from(result).toString('base64')).to.equal('Gw4A+KWpyubolCCjVAjmxJ4D');
47+
});
48+
2449
it("cleanly fails when decompressing garbage", () => {
2550
const input = Buffer.from("This is not brotli data, it's just a string");
2651
expect(() =>
@@ -35,4 +60,12 @@ describe("Brotli-wasm", () => {
3560
).toString('utf8');
3661
expect(result).to.equal(input);
3762
});
38-
});
63+
64+
it("can compress & decompress back to the original result with a different quality setting", () => {
65+
const input = "Some thrilling text I urgently need to compress";
66+
const result = Buffer.from(
67+
brotli.decompress(brotli.compress(Buffer.from(input), { quality: 3 }))
68+
).toString('utf8');
69+
expect(result).to.equal(input);
70+
});
71+
});

0 commit comments

Comments
 (0)