wasm-bundle 0.3.0

Compile Rust code to self-contained `.js` and `.html` files using WASM.
Documentation
use std::{
    fs::File,
    io::{copy, Write},
    path::PathBuf,
};

use base64::{engine::general_purpose::STANDARD, write::EncoderWriter};

pub fn pack(name: &str, wasm_bindgen_target_dir: &PathBuf, html_target_dir: &PathBuf) {
    let js_path = html_target_dir.join(format!("{name}.js"));
    let html_path = html_target_dir.join(format!("{name}.html"));
    {
        let mut wasm = File::open(wasm_bindgen_target_dir.join(format!("{name}_bg.wasm"))).unwrap();
        let mut jsin = File::open(wasm_bindgen_target_dir.join(format!("{name}.js"))).unwrap();

        let mut js = File::create(&js_path).unwrap();
        js.write_all("let js_base64 = \"".as_bytes()).unwrap();
        let mut enc = EncoderWriter::new(&mut js, &STANDARD);
        copy(&mut jsin, &mut enc).unwrap();
        enc.finish().unwrap();
        drop(enc);
        js.write_all("\";\n".as_bytes()).unwrap();

        copy(&mut jsin, &mut js).unwrap();
        js.write_all("let wasm_base64 = \"".as_bytes()).unwrap();
        let mut enc = EncoderWriter::new(&mut js, &STANDARD);
        copy(&mut wasm, &mut enc).unwrap();
        enc.finish().unwrap();
        drop(enc);
        js.write_all("\";\n".as_bytes()).unwrap();

        js.write_all(
            r#"
const mod = await import('data:application/javascript;base64,'+js_base64);
let wasm_buffer = Uint8Array.from(atob(wasm_base64), c => c.charCodeAt(0)).buffer;
async function init() {
    await mod.default(wasm_buffer);
}
export default init;
"#
            .as_bytes(),
        )
        .unwrap();
        js.sync_all().unwrap();
        eprintln!("Generated: {}", js_path.as_path().to_string_lossy())
    }
    {
        let mut js = File::open(&js_path).unwrap();
        let mut html = File::create(&html_path).unwrap();
        html.write_all(
            r#"<html>
<head>
    <meta charset="UTF-8">
    <title>"#
                .as_bytes(),
        )
        .unwrap();
        html.write_all(name.as_bytes()).unwrap();
        html.write_all(
            r#"</title>
</head>
<body>
    <script type="module">
"#
            .as_bytes(),
        )
        .unwrap();
        copy(&mut js, &mut html).unwrap();
        html.write_all(
            r#"
init();
        </script>
    </body>
</html>"#
                .as_bytes(),
        )
        .unwrap();
        html.sync_all().unwrap();
        eprintln!("Generated: {}", html_path.as_path().to_string_lossy())
    }
}