yew_stdweb/services/
storage.rs1use crate::format::Text;
5use cfg_if::cfg_if;
6use cfg_match::cfg_match;
7use std::fmt;
8use thiserror::Error;
9cfg_if! {
10 if #[cfg(feature = "std_web")] {
11 #[allow(unused_imports)]
12 use stdweb::{_js_impl, js};
13 use stdweb::unstable::TryFrom;
14 use stdweb::web::{Storage};
15 } else if #[cfg(feature = "web_sys")] {
16 use crate::utils;
17 use web_sys::Storage;
18 }
19}
20
21#[derive(Debug, Error)]
23enum StorageError {
24 #[error("restore error")]
25 CantRestore,
26}
27
28#[derive(Debug)]
30pub enum Area {
31 Local,
33 Session,
35}
36
37pub struct StorageService {
39 storage: Storage,
40}
41
42impl fmt::Debug for StorageService {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 f.write_str("StorageService")
45 }
46}
47
48impl StorageService {
49 pub fn new(area: Area) -> Result<Self, &'static str> {
51 let storage = cfg_match! {
52 feature = "std_web" => ({
53 let storage_name = match area {
54 Area::Local => "localStorage",
55 Area::Session => "sessionStorage",
56 };
57 let storage = js! {
58 try {
59 return window[@{storage_name}];
60 } catch(error) {
61 return error;
62 }
63 };
64 Storage::try_from(js!( return @{storage.as_ref()}; ))
65 }),
66 feature = "web_sys" => ({
67 let storage = {
68 match area {
69 Area::Local => utils::window().local_storage(),
70 Area::Session => utils::window().session_storage(),
71 }
72 };
73 storage.map(Option::unwrap)
74 }),
75 };
76
77 storage
78 .map(|storage| StorageService { storage })
79 .map_err(|_| "couldn't aquire storage")
80 }
81
82 pub fn store<T>(&mut self, key: &str, value: T)
84 where
85 T: Into<Text>,
86 {
87 if let Ok(data) = value.into() {
88 let result = cfg_match! {
89 feature = "std_web" => self.storage.insert(key, &data),
90 feature = "web_sys" => self.storage.set_item(key, &data),
91 };
92 result.expect("can't insert value to a storage");
93 }
94 }
95
96 pub fn restore<T>(&self, key: &str) -> T
98 where
99 T: From<Text>,
100 {
101 let data = cfg_match! {
102 feature = "std_web" => self.storage.get(key),
103 feature = "web_sys" => self.storage.get_item(key).unwrap(),
104 };
105 let data = data.ok_or_else(|| StorageError::CantRestore.into());
106 T::from(data)
107 }
108
109 pub fn remove(&mut self, key: &str) {
111 cfg_match! {
112 feature = "std_web" => self.storage.remove(key),
113 feature = "web_sys" => self.storage.remove_item(key).unwrap(),
114 };
115 }
116}