inkpad_browser/
tree.rs

1//! Browser storage
2use inkpad_executor::Memory;
3use inkpad_std::{Rc, Vec};
4use inkpad_support::{
5    traits::{Cache, Frame, Storage},
6    types::State,
7};
8use core::cell::RefCell;
9use wasm_bindgen::prelude::wasm_bindgen;
10
11/// Browser storage
12#[wasm_bindgen]
13pub struct Tree {
14    name: String,
15    storage: web_sys::Storage,
16    frame: Vec<Rc<RefCell<State<Memory>>>>,
17}
18
19#[wasm_bindgen]
20impl Tree {
21    #[wasm_bindgen(constructor)]
22    pub fn new(name: &str) -> Self {
23        let window = web_sys::window().expect("Could not find window");
24        Self {
25            name: name.to_string(),
26            storage: window
27                .local_storage()
28                .expect("Could not find local_storage")
29                .expect("Could not find local_storage"),
30            frame: Vec::new(),
31        }
32    }
33}
34
35fn browser_key(mut name: String, code_hash: Vec<u8>) -> String {
36    name.push_str(&hex::encode(code_hash));
37    name
38}
39
40impl Storage for Tree {
41    fn set(&mut self, key: Vec<u8>, value: Vec<u8>) -> Option<Vec<u8>> {
42        let data_str = serde_json::to_string(&value).ok()?;
43        self.storage
44            .set(&browser_key(self.name.to_string(), key.clone()), &data_str)
45            .map(|_| key)
46            .ok()
47    }
48
49    fn remove(&mut self, key: &[u8]) -> Option<Vec<u8>> {
50        let data_str = serde_json::to_string(&key).ok()?;
51        self.storage
52            .remove_item(&data_str)
53            .ok()
54            .map(|_| key.to_vec())
55    }
56
57    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
58        if let Ok(Some(data)) = self
59            .storage
60            .get(&browser_key(self.name.to_string(), key.to_vec()))
61        {
62            Some(serde_json::from_str(&data).ok()?)
63        } else {
64            None
65        }
66    }
67}
68
69impl Frame<Memory> for Tree {}
70
71impl Cache<Memory> for Tree {
72    fn frame(&self) -> &Vec<Rc<RefCell<State<Memory>>>> {
73        &self.frame
74    }
75
76    fn frame_mut(&mut self) -> &mut Vec<Rc<RefCell<State<Memory>>>> {
77        &mut self.frame
78    }
79
80    fn memory(&self) -> Option<Memory> {
81        Some(self.frame.last()?.borrow().memory.clone())
82    }
83}