batbox_preferences/
lib.rs1#![warn(missing_docs)]
5
6use serde::{de::DeserializeOwned, Serialize};
7
8pub fn base_path() -> std::path::PathBuf {
10 #[cfg(target_arch = "wasm32")]
11 {
12 ".".into() }
14 #[cfg(not(target_arch = "wasm32"))]
15 {
16 let exe = std::env::current_exe().expect("Failed to find current exe");
17 let app_name = exe.file_stem().unwrap();
18 if let Some(dirs) =
19 directories::ProjectDirs::from("", "", app_name.to_str().expect("Exe name is invalid"))
20 {
21 return dirs.preference_dir().to_path_buf();
22 }
23 if let Some(dir) = exe.parent() {
24 return dir.to_path_buf();
25 }
26 std::env::current_dir().unwrap()
27 }
28}
29
30pub fn save<T: Serialize>(key: &str, value: &T) {
32 let base_path = base_path();
33 let path = base_path.join(key);
34 #[cfg(target_arch = "wasm32")]
35 {
36 let path = path.to_str().unwrap();
37 if let Ok(Some(storage)) = web_sys::window().unwrap().local_storage() {
38 if let Err(e) = storage.set_item(
39 path,
40 &serde_json::to_string(value).expect("Failed to serialize"),
41 ) {
42 let _ = e; }
44 }
45 }
46 #[cfg(not(target_arch = "wasm32"))]
47 {
48 use std::io::Write;
49 if let Err(e) = std::fs::create_dir_all(&base_path) {
50 log::error!("Failed to create preferences base path: {}", e);
51 return;
52 }
53 let path = &path;
54 let mut file = match std::fs::File::create(path) {
55 Ok(file) => file,
56 Err(e) => {
57 log::error!("Failed to create {:?}: {}", path, e);
58 return;
59 }
60 };
61 if let Err(e) = file.write_all(serde_json::to_string_pretty(value).unwrap().as_bytes()) {
62 log::error!("Failed to save {:?}: {}", path, e);
63 }
64 }
65}
66
67pub fn load<T: DeserializeOwned>(key: &str) -> Option<T> {
69 let base_path = base_path();
70 let path = base_path.join(key);
71 #[cfg(target_arch = "wasm32")]
72 {
73 let path = path.to_str().unwrap();
74 if let Ok(Some(storage)) = web_sys::window().unwrap().local_storage() {
75 match storage
76 .get_item(path)
77 .ok()
78 .flatten()
79 .map(|s| serde_json::from_str(&s))
80 {
81 Some(Ok(value)) => Some(value),
82 Some(Err(e)) => {
83 log::error!("Failed to deserialize {:?}: {}", path, e);
84 None
85 }
86 None => None,
87 }
88 } else {
89 None
90 }
91 }
92 #[cfg(not(target_arch = "wasm32"))]
93 {
94 let path = &path;
95 let file = match std::fs::File::open(path) {
96 Ok(file) => file,
97 Err(e) => {
98 log::warn!("Failed to open {:?}: {}", path, e);
99 return None;
100 }
101 };
102 match serde_json::from_reader(file) {
103 Ok(value) => {
104 log::debug!("Successfully loaded {:?}", path);
105 Some(value)
106 }
107 Err(e) => {
108 log::error!("Failed to deserialize {:?}: {}", path, e);
109 None
110 }
111 }
112 }
113}