1#[macro_export]
2macro_rules! MaybeStoredKey {
22 ($key_name:ident, Value = $val:ty, Path = $path:expr, Serialize = $serialize:expr, Deserialize = $deserialize:expr) => {
23 use $crate::re_exports::*;
24
25 static DATA: Global<Signal<Option<Option<$val>>, SyncStorage>> =
26 Global::new(|| Signal::new_maybe_sync(None));
27
28 impl DataKey for $key_name {
29 type Value = Option<$val>;
30
31 async fn init() {
32 let path = PathBuf::from($path);
33 if path.try_exists().unwrap() {
34 let mut file = File::open(path).await.unwrap();
35 let mut contents = Vec::new();
36 file.read_to_end(&mut contents).await.unwrap();
37 *DATA.resolve().write() = Some(Some(($deserialize)(&contents)));
38 } else {
39 *DATA.resolve().write() = Some(None);
40 }
41 }
42
43 async fn on_change() {
44 let resolve = DATA.resolve();
45 let read = resolve.read();
46 let Some(data) = read.deref().as_ref() else {
47 return;
48 };
49
50 if let Some(data) = data {
51 let mut file = File::create(PathBuf::from($path)).await.unwrap();
52 file.write_all(&($serialize)(data)).await.unwrap();
53 } else {
54 let _ = remove_file($path).await;
55 }
56 }
57
58 async fn on_drop() {}
59
60 fn try_read() -> Option<ReadableRef<'static, Signal<Self::Value, SyncStorage>>> {
61 SyncStorage::try_map(DATA.resolve().read_unchecked(), |v| v.as_ref())
62 }
63
64 fn try_peek() -> Option<ReadableRef<'static, Signal<Self::Value, SyncStorage>>> {
65 SyncStorage::try_map(DATA.resolve().peek_unchecked(), |v| v.as_ref())
66 }
67 }
68
69 impl WritableDataKey for $key_name {
70 fn try_write() -> Option<WritableRef<'static, Signal<Self::Value, SyncStorage>>> {
71 Signal::<Option<Self::Value>, SyncStorage>::try_map_mut(
72 DATA.resolve().write_unchecked(),
73 |v| v.as_mut(),
74 )
75 }
76 }
77 };
78}
79
80#[macro_export]
81macro_rules! StoredKey {
102 ($key_name:ident, Value = $val:ty, Path = $path:expr, Default = $default:expr, Serialize = $serialize:expr, Deserialize = $deserialize:expr) => {
103 use $crate::re_exports::*;
104
105 static DATA: Global<Signal<Option<$val>, SyncStorage>> =
106 Global::new(|| Signal::new_maybe_sync(None));
107
108 impl DataKey for $key_name {
109 type Value = $val;
110
111 async fn init() {
112 let path = PathBuf::from($path);
113 if path.try_exists().unwrap() {
114 let mut file = File::open(path).await.unwrap();
115 let mut contents = Vec::new();
116 file.read_to_end(&mut contents).await.unwrap();
117 *DATA.resolve().write() = Some(($deserialize)(&contents));
118 } else {
119 let default = $default;
120 let mut file = File::create(path).await.unwrap();
121 file.write_all(&($serialize)(&default)).await.unwrap();
122 *DATA.resolve().write() = Some(default);
123 }
124 }
125
126 async fn on_change() {
127 let mut file = File::create(PathBuf::from($path)).await.unwrap();
128 file.write_all(&($serialize)(
129 DATA.resolve().read().deref().as_ref().unwrap(),
130 ))
131 .await
132 .unwrap();
133 }
134
135 async fn on_drop() {}
136
137 fn try_read() -> Option<ReadableRef<'static, Signal<Self::Value, SyncStorage>>> {
138 SyncStorage::try_map(DATA.resolve().read_unchecked(), |v| v.as_ref())
139 }
140
141 fn try_peek() -> Option<ReadableRef<'static, Signal<Self::Value, SyncStorage>>> {
142 SyncStorage::try_map(DATA.resolve().peek_unchecked(), |v| v.as_ref())
143 }
144 }
145
146 impl WritableDataKey for $key_name {
147 fn try_write() -> Option<WritableRef<'static, Signal<Self::Value, SyncStorage>>> {
148 Signal::<Option<Self::Value>, SyncStorage>::try_map_mut(
149 DATA.resolve().write_unchecked(),
150 |v| v.as_mut(),
151 )
152 }
153 }
154 };
155}