1use crate::result::Result;
2use cfg_if::cfg_if;
3use std::collections::hash_map::DefaultHasher;
4use std::hash::{Hash, Hasher};
5
6cfg_if! {
7 if #[cfg(not(target_arch = "wasm32"))] {
8 use std::path::PathBuf;
9 use tokio::fs;
10 } else {
11 }
13}
14
15pub struct Store {
23 pub linux: Option<String>,
25 pub macos: Option<String>,
27 pub unix: Option<String>,
29 pub windows: Option<String>,
31 pub generic: Option<String>,
33 pub browser: Option<String>,
35}
36
37impl Default for Store {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl Store {
44 pub fn new() -> Store {
46 Store {
47 linux: None,
48 macos: None,
49 unix: None,
50 windows: None,
51 generic: None,
52 browser: None,
53 }
54 }
55
56 pub fn with_linux(&mut self, linux: &str) -> &mut Store {
58 self.linux = Some(linux.to_string());
59 self
60 }
61
62 pub fn with_macos(&mut self, macos: &str) -> &mut Store {
64 self.macos = Some(macos.to_string());
65 self
66 }
67
68 pub fn with_unix(&mut self, unix: &str) -> &mut Store {
70 self.unix = Some(unix.to_string());
71 self
72 }
73
74 pub fn with_windows(&mut self, windows: &str) -> &mut Store {
76 self.windows = Some(windows.to_string());
77 self
78 }
79
80 pub fn with_generic(&mut self, generic: &str) -> &mut Store {
82 self.generic = Some(generic.to_string());
83 self
84 }
85
86 pub fn with_browser(&mut self, browser: &str) -> &mut Store {
88 self.browser = Some(browser.to_string());
89 self
90 }
91
92 pub fn filename(&self) -> String {
96 cfg_if! {
97 if #[cfg(target_os = "macos")] {
98 find(&[self.macos.as_ref(),self.unix.as_ref(),self.generic.as_ref()])
99 } else if #[cfg(target_os = "linux")] {
100 find(&[self.linux.as_ref(),self.unix.as_ref(),self.generic.as_ref()])
101 } else if #[cfg(target_family = "unix")] {
102 find(&[self.unix.as_ref(),self.generic.as_ref()])
103 } else if #[cfg(target_family = "windows")] {
104 find(&[self.windows.as_ref(),self.generic.as_ref()])
105 } else if #[cfg(target_arch = "wasm32")] {
106 if let Some(browser) = self.browser.as_ref() {
107 browser.clone()
108 } else if let Some(generic) = self.generic.as_ref() {
109 hash(generic)
111 } else {
112 panic!("no path found for the current operating environment");
113 }
114 }
115 }
116 }
117
118 cfg_if! {
119 if #[cfg(target_arch = "wasm32")] {
120 pub async fn exists(&self) -> Result<bool> {
121 let filename = self.filename();
122 Ok(local_storage().get_item(&filename)?.is_some())
123 }
124
125 pub async fn read_to_string(&self) -> Result<String> {
126 let filename = self.filename();
127 let v = local_storage().get_item(&filename)?.unwrap();
128 Ok(v)
130 }
131
132 pub async fn write_string(&self, data: &str) -> Result<()> {
133 let filename = self.filename();
134 local_storage().set_item(&filename, data)?;
136 Ok(())
137 }
138
139 } else {
140 pub async fn exists(&self) -> Result<bool> {
142 let filename = parse(self.filename());
143 Ok(fs::metadata(&filename).await.is_ok())
144 }
145
146 pub async fn read_to_string(&self) -> Result<String> {
148 let filename = parse(self.filename());
149 Ok(fs::read_to_string(&filename).await?)
150 }
151
152 pub async fn write_string(&self, data: &str) -> Result<()> {
155 let filename = parse(self.filename());
156 Ok(fs::write(&filename, data).await?)
157 }
158 }
159 }
160}
161
162cfg_if! {
163 if #[cfg(not(target_arch = "wasm32"))] {
164 pub fn parse(path : String) -> PathBuf {
167
168 if let Some(stripped) = path.strip_prefix('~') {
169 let home_dir: PathBuf = home::home_dir().unwrap();
170 home_dir.join(stripped)
171 } else {
172 PathBuf::from(path)
173 }
174 }
175 } else {
176 pub fn local_storage() -> web_sys::Storage {
177 web_sys::window().unwrap().local_storage().unwrap().unwrap()
178 }
179 }
180}
181
182pub fn find(paths: &[Option<&String>]) -> String {
185 for path in paths.iter() {
186 if let Some(path) = *path {
187 return path.clone();
188 }
189 }
190 panic!("no path found for the current operating environment");
191}
192
193pub fn hash<T>(t: T) -> String
196where
197 T: Hash,
198{
199 let mut hasher = DefaultHasher::new();
200 t.hash(&mut hasher);
201 let v = hasher.finish();
202 format!("{v:x}")
203}