1use js_sys::Uint8Array;
2use wasm_bindgen::{prelude::*, JsCast};
3
4pub fn save_file(data: &[u8], filename: &str, mime_type: Option<&str>) -> Result<(), JsValue> {
5 let content = Uint8Array::new_with_length(data.len() as u32);
7 content.copy_from(data);
8
9 let blob_parts = js_sys::Array::new();
10 blob_parts.push(&content);
11
12 let blob = match mime_type {
13 Some(mime_type) => {
14 let mut blob_options = web_sys::BlobPropertyBag::new();
15 blob_options.type_(mime_type);
16 web_sys::Blob::new_with_u8_array_sequence_and_options(&blob_parts, &blob_options)?
17 },
18 None => {
19 web_sys::Blob::new_with_u8_array_sequence(&blob_parts)?
20 }
21 };
22
23 let blob_url = web_sys::Url::create_object_url_with_blob(&blob)?;
24
25 let document = web_sys::window().unwrap().document().unwrap();
26
27 let elem:web_sys::HtmlAnchorElement = document.create_element("a")?.unchecked_into();
28
29 elem.set_attribute("href", &blob_url)?;
30 elem.set_attribute("download", filename)?;
31
32 let body = document.body().ok_or_else(|| JsValue::from_str("unable to get document body"))?;
33 body.append_child(&elem)?;
34
35 elem.click();
36
37 body.remove_child(&elem)?;
38
39 web_sys::Url::revoke_object_url(&blob_url)?;
40
41 Ok(())
42}