1use snafu::prelude::*;
3
4#[derive(Debug, Snafu)]
6pub enum LoadingBytesError {
7 #[snafu(display("loading '{path}' by WASM error: {msg:#?}"))]
8 Wasm {
9 path: String,
10 msg: wasm_bindgen::JsValue,
11 },
12 #[snafu(display("loading '{path}' by filesystem from CWD '{}' error: {source}", cwd.display()))]
13 Fs {
14 path: String,
15 cwd: std::path::PathBuf,
16 source: std::io::Error,
17 },
18}
19
20pub async fn load(path: &str) -> Result<Vec<u8>, LoadingBytesError> {
23 #[cfg(target_arch = "wasm32")]
24 {
25 use wasm_bindgen::JsCast;
26
27 let path = path.to_string();
28 let mut opts = web_sys::RequestInit::new();
29 opts.method("GET");
30 let request = web_sys::Request::new_with_str_and_init(&path, &opts).map_err(|msg| {
31 LoadingBytesError::Wasm {
32 path: path.clone(),
33 msg,
34 }
35 })?;
36 let window = web_sys::window().unwrap();
37 let resp_value = wasm_bindgen_futures::JsFuture::from(window.fetch_with_request(&request))
38 .await
39 .map_err(|msg| LoadingBytesError::Wasm {
40 path: path.clone(),
41 msg,
42 })?;
43 let resp: web_sys::Response =
44 resp_value
45 .dyn_into()
46 .map_err(|msg| LoadingBytesError::Wasm {
47 path: path.clone(),
48 msg,
49 })?;
50 let array_promise = resp.array_buffer().map_err(|msg| LoadingBytesError::Wasm {
51 path: path.clone(),
52 msg,
53 })?;
54 let buffer = wasm_bindgen_futures::JsFuture::from(array_promise)
55 .await
56 .map_err(|msg| LoadingBytesError::Wasm {
57 path: path.clone(),
58 msg,
59 })?;
60 assert!(buffer.is_instance_of::<js_sys::ArrayBuffer>());
61 let array: js_sys::Uint8Array = js_sys::Uint8Array::new(&buffer);
62 let mut bytes: Vec<u8> = vec![0; array.length() as usize];
63 array.copy_to(&mut bytes);
64 Ok(bytes)
65 }
66 #[cfg(not(target_arch = "wasm32"))]
67 {
68 let bytes: Vec<u8> = async_fs::read(path).await.with_context(|_| FsSnafu {
69 path: path.to_string(),
70 cwd: std::env::current_dir().unwrap(),
71 })?;
72 Ok(bytes)
73 }
74}