forked from denoland/wasmbuild
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.rs
More file actions
95 lines (86 loc) · 2.38 KB
/
lib.rs
File metadata and controls
95 lines (86 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::collections::HashMap;
use anyhow::bail;
use anyhow::Result;
use wasm_bindgen::prelude::*;
// uncomment for debugging
// #[wasm_bindgen]
// extern "C" {
// #[wasm_bindgen(js_namespace = console)]
// fn log(s: &str);
// }
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BindgenTextFileOutput {
pub name: String,
pub text: String,
}
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BindgenBytesFileOutput {
pub name: String,
pub bytes: Vec<u8>,
}
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Output {
pub js_bg: BindgenTextFileOutput,
pub ts: Option<BindgenTextFileOutput>,
pub snippets: HashMap<String, Vec<String>>,
pub local_modules: HashMap<String, String>,
pub start: Option<String>,
pub wasm: BindgenBytesFileOutput,
}
#[wasm_bindgen]
pub fn generate_bindgen(
name: &str,
ext: &str,
wasm_bytes: Vec<u8>,
) -> Result<JsValue, JsValue> {
let output = inner(name, ext, wasm_bytes)
.map_err(|err| JsValue::from(js_sys::Error::new(&err.to_string())))?;
let output = serde_wasm_bindgen::to_value(&output)
.map_err(|err| JsValue::from(js_sys::Error::new(&err.to_string())))?;
Ok(output)
}
fn inner(name: &str, ext: &str, wasm_bytes: Vec<u8>) -> Result<Output> {
let mut x = wasm_bindgen_cli_support::Bindgen::new()
.bundler(true)?
.typescript(true)
.input_bytes(name, wasm_bytes)
.generate_output()?;
let searching_module = format!("./{}_bg.js", name);
let wasm_mut = x.wasm_mut();
for import in wasm_mut.imports.iter_mut() {
if import.module == searching_module {
import.module = format!("./{name}.internal.{ext}");
}
}
Ok(Output {
js_bg: BindgenTextFileOutput {
name: format!("{}.internal.{}", name, ext),
text: x.js().to_string(),
},
ts: match x.ts() {
Some(t) => Some(BindgenTextFileOutput {
name: format!(
"{}.d.{}",
name,
match ext {
"js" => "ts",
"mjs" => "mts",
_ => bail!("Unsupported extension: {}", ext),
}
),
text: t.to_string(),
}),
None => None,
},
snippets: x.snippets().clone(),
local_modules: x.local_modules().clone(),
start: x.start().cloned(),
wasm: BindgenBytesFileOutput {
name: format!("{}.wasm", name),
bytes: x.wasm_mut().emit_wasm(),
},
})
}