magicstatemachines/shared/
storage.rs1use crate::state_trait::ErasedState;
2use core::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
3use core::fmt;
4use core::ops::{Deref, DerefMut};
5#[cfg(feature = "std")]
6use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockError};
7
8pub struct SharedValue<T> {
13 pub(super) state: ErasedState,
14 pub(super) value: T,
15}
16
17#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub struct WrongStateError {
20 pub expected: &'static str,
22 pub actual: &'static str,
24}
25
26impl fmt::Display for WrongStateError {
27 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
28 write!(
29 formatter,
30 "expected state {}, found {}",
31 self.expected, self.actual
32 )
33 }
34}
35
36#[cfg(feature = "std")]
37impl std::error::Error for WrongStateError {}
38
39#[derive(Debug)]
41pub enum SharedStateError<StorageError = core::convert::Infallible> {
42 WrongState(WrongStateError),
44 Storage(StorageError),
46}
47
48impl<StorageError> fmt::Display for SharedStateError<StorageError>
49where
50 StorageError: fmt::Display,
51{
52 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
53 match self {
54 Self::WrongState(error) => error.fmt(formatter),
55 Self::Storage(error) => error.fmt(formatter),
56 }
57 }
58}
59
60#[cfg(feature = "std")]
61impl<StorageError> std::error::Error for SharedStateError<StorageError> where
62 StorageError: fmt::Debug + fmt::Display
63{
64}
65
66impl<StorageError> From<WrongStateError> for SharedStateError<StorageError> {
67 fn from(error: WrongStateError) -> Self {
68 Self::WrongState(error)
69 }
70}
71
72pub trait SharedStorageView {
78 type Storage<T>;
80
81 type ReadGuard<'a, T>: Deref<Target = SharedValue<T>>
83 where
84 Self: 'a,
85 T: 'a;
86
87 type WriteGuard<'a, T>: DerefMut<Target = SharedValue<T>>
89 where
90 Self: 'a,
91 T: 'a;
92}
93
94pub trait SharedStorage {
140 type Storage<T>;
142
143 type ReadGuard<'a, T>: Deref<Target = SharedValue<T>>
145 where
146 Self: 'a,
147 T: 'a;
148
149 type WriteGuard<'a, T>: DerefMut<Target = SharedValue<T>>
151 where
152 Self: 'a,
153 T: 'a;
154
155 type ReadError<'a, T>
157 where
158 Self: 'a,
159 T: 'a;
160
161 type WriteError<'a, T>
163 where
164 Self: 'a,
165 T: 'a;
166
167 fn new<T>(value: SharedValue<T>) -> Self::Storage<T>;
169 fn read<T>(
171 storage: &Self::Storage<T>,
172 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>>;
173 fn write<T>(
175 storage: &Self::Storage<T>,
176 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>>;
177}
178
179impl<Storage> SharedStorageView for Storage
180where
181 Storage: SharedStorage,
182{
183 type Storage<T> = <Storage as SharedStorage>::Storage<T>;
184 type ReadGuard<'a, T>
185 = <Storage as SharedStorage>::ReadGuard<'a, T>
186 where
187 Storage: 'a,
188 T: 'a;
189 type WriteGuard<'a, T>
190 = <Storage as SharedStorage>::WriteGuard<'a, T>
191 where
192 Storage: 'a,
193 T: 'a;
194}
195
196pub struct RefCellStorage;
198
199impl SharedStorage for RefCellStorage {
200 type Storage<T> = RefCell<SharedValue<T>>;
201 type ReadGuard<'a, T>
202 = Ref<'a, SharedValue<T>>
203 where
204 T: 'a;
205 type WriteGuard<'a, T>
206 = RefMut<'a, SharedValue<T>>
207 where
208 T: 'a;
209 type ReadError<'a, T>
210 = BorrowError
211 where
212 T: 'a;
213 type WriteError<'a, T>
214 = BorrowMutError
215 where
216 T: 'a;
217
218 fn new<T>(value: SharedValue<T>) -> Self::Storage<T> {
219 RefCell::new(value)
220 }
221
222 fn read<T>(
223 storage: &Self::Storage<T>,
224 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>> {
225 storage.try_borrow()
226 }
227
228 fn write<T>(
229 storage: &Self::Storage<T>,
230 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>> {
231 storage.try_borrow_mut()
232 }
233}
234
235#[cfg(feature = "std")]
237pub struct MutexStorage;
238
239#[cfg(feature = "std")]
240impl SharedStorage for MutexStorage {
241 type Storage<T> = Mutex<SharedValue<T>>;
242 type ReadGuard<'a, T>
243 = MutexGuard<'a, SharedValue<T>>
244 where
245 T: 'a;
246 type WriteGuard<'a, T>
247 = MutexGuard<'a, SharedValue<T>>
248 where
249 T: 'a;
250 type ReadError<'a, T>
251 = TryLockError<MutexGuard<'a, SharedValue<T>>>
252 where
253 T: 'a;
254 type WriteError<'a, T>
255 = TryLockError<MutexGuard<'a, SharedValue<T>>>
256 where
257 T: 'a;
258
259 fn new<T>(value: SharedValue<T>) -> Self::Storage<T> {
260 Mutex::new(value)
261 }
262
263 fn read<T>(
264 storage: &Self::Storage<T>,
265 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>> {
266 storage.try_lock()
267 }
268
269 fn write<T>(
270 storage: &Self::Storage<T>,
271 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>> {
272 storage.try_lock()
273 }
274}
275
276#[cfg(feature = "std")]
278pub struct RwLockStorage;
279
280#[cfg(feature = "std")]
281impl SharedStorage for RwLockStorage {
282 type Storage<T> = RwLock<SharedValue<T>>;
283 type ReadGuard<'a, T>
284 = RwLockReadGuard<'a, SharedValue<T>>
285 where
286 T: 'a;
287 type WriteGuard<'a, T>
288 = RwLockWriteGuard<'a, SharedValue<T>>
289 where
290 T: 'a;
291 type ReadError<'a, T>
292 = TryLockError<RwLockReadGuard<'a, SharedValue<T>>>
293 where
294 T: 'a;
295 type WriteError<'a, T>
296 = TryLockError<RwLockWriteGuard<'a, SharedValue<T>>>
297 where
298 T: 'a;
299
300 fn new<T>(value: SharedValue<T>) -> Self::Storage<T> {
301 RwLock::new(value)
302 }
303
304 fn read<T>(
305 storage: &Self::Storage<T>,
306 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>> {
307 storage.try_read()
308 }
309
310 fn write<T>(
311 storage: &Self::Storage<T>,
312 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>> {
313 storage.try_write()
314 }
315}