save.rsannotatedsave.rssource50 lines · 1.6 KB · raw
1use crate::js;
2use js_sys::{Array, Object, Uint8Array};
3use std::collections::HashMap;
4use wasm_bindgen::{JsCast, JsValue};
5use wasm_bindgen_futures::JsFuture;
6
7pub async fn load_all(file_name: &str) -> HashMap<String, Vec<u8>> {
8    try_load_all(file_name).await.unwrap_or_else(|err| {
9        log::error!(
10            "Error reading save files for file {file_name}: {}",
11            err.as_string().unwrap_or_default()
12        );
13        HashMap::new()
14    })
15}
16
17async fn try_load_all(file_name: &str) -> Result<HashMap<String, Vec<u8>>, JsValue> {
18    let files = JsFuture::from(js::loadSaveFiles(file_name)).await?;
19    let files = files.dyn_into::<Object>()?;
20
21    let mut files_map: HashMap<String, Vec<u8>> = HashMap::new();
22    for file in Object::entries(&files) {
23        let file = file.dyn_into::<Array>()?;
24
25        let Some(extension) = file.get(0).as_string() else {
26            return Err(JsValue::from_str("Invalid data in IndexedDB"));
27        };
28        let bytes = file.get(1).dyn_into::<Uint8Array>()?;
29
30        files_map.insert(extension, bytes.to_vec());
31    }
32
33    Ok(files_map)
34}
35
36pub async fn write(file_name: &str, extension: &str, bytes: &[u8]) {
37    if let Err(err) = try_write(file_name, extension, bytes).await {
38        log::error!(
39            "Error persisting save file for file {file_name} extension {extension}: {}",
40            err.as_string().unwrap_or_default()
41        );
42    }
43}
44
45async fn try_write(file_name: &str, extension: &str, bytes: &[u8]) -> Result<(), JsValue> {
46    let array = Uint8Array::new_from_slice(bytes);
47    JsFuture::from(js::writeSaveFile(file_name, extension, array)).await?;
48
49    Ok(())
50}