aboutsummaryrefslogtreecommitdiffstats
path: root/src/wasm.rs
blob: a273994d56f72e49569b51134c8aa2352194122b (plain)
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
use std::path::PathBuf;
use std::{io, io::Write};
use web_sys::js_sys::Array;
use web_sys::wasm_bindgen::{JsCast, JsValue};
use web_sys::{Blob, BlobPropertyBag, HtmlAnchorElement, HtmlCanvasElement, Url};

pub fn get_canvas_element() -> Option<HtmlCanvasElement> {
    let document = web_sys::window()?.document()?;
    let canvas = document.get_element_by_id("nodetoy")?;
    canvas.dyn_into::<HtmlCanvasElement>().ok()
}

pub struct DownloadFile {
    data: Vec<u8>,
    filename: PathBuf,
    options: BlobPropertyBag,
}

impl DownloadFile {
    pub fn new(filename: PathBuf, mime_type: &str) -> Self {
        let options = BlobPropertyBag::new();
        options.set_type(mime_type);

        Self {
            data: Vec::new(),
            filename,
            options,
        }
    }

    pub fn save(&self) -> Result<(), JsValue> {
        let string = unsafe { str::from_utf8_unchecked(&self.data) };
        let parts = Array::of1(&JsValue::from_str(string));
        let blob = Blob::new_with_str_sequence_and_options(&parts, &self.options)?;
        let url = Url::create_object_url_with_blob(&blob)?;

        let document = web_sys::window().unwrap().document().unwrap();
        let a: HtmlAnchorElement = document.create_element("a")?.dyn_into()?;

        a.set_href(&url);
        a.set_download(&self.filename.as_os_str().to_string_lossy());
        a.click();

        Url::revoke_object_url(&url)?;
        Ok(())
    }
}

impl Write for DownloadFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.data.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.data.flush()
    }
}

impl Drop for DownloadFile {
    fn drop(&mut self) {
        self.save().unwrap()
    }
}