magicstatemachines/shared/
storage.rs1use crate::state_trait::ErasedState;
2use core::fmt;
3use core::ops::{Deref, DerefMut};
4use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
5use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockError};
6
7pub struct SharedValue<T> {
12 pub(super) state: ErasedState,
13 pub(super) value: T,
14}
15
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
18pub struct WrongStateError {
19 pub expected: &'static str,
21 pub actual: &'static str,
23}
24
25impl fmt::Display for WrongStateError {
26 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
27 write!(
28 formatter,
29 "expected state {}, found {}",
30 self.expected, self.actual
31 )
32 }
33}
34
35impl std::error::Error for WrongStateError {}
36
37#[derive(Debug)]
39pub enum SharedStateError<StorageError = core::convert::Infallible> {
40 WrongState(WrongStateError),
42 Storage(StorageError),
44}
45
46impl<StorageError> fmt::Display for SharedStateError<StorageError>
47where
48 StorageError: fmt::Display,
49{
50 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
51 match self {
52 Self::WrongState(error) => error.fmt(formatter),
53 Self::Storage(error) => error.fmt(formatter),
54 }
55 }
56}
57
58impl<StorageError> std::error::Error for SharedStateError<StorageError> where
59 StorageError: fmt::Debug + fmt::Display
60{
61}
62
63impl<StorageError> From<WrongStateError> for SharedStateError<StorageError> {
64 fn from(error: WrongStateError) -> Self {
65 Self::WrongState(error)
66 }
67}
68
69pub trait SharedStorage {
115 type Storage<T>;
117
118 type ReadGuard<'a, T>: Deref<Target = SharedValue<T>>
120 where
121 Self: 'a,
122 T: 'a;
123
124 type WriteGuard<'a, T>: DerefMut<Target = SharedValue<T>>
126 where
127 Self: 'a,
128 T: 'a;
129
130 type ReadError<'a, T>
132 where
133 Self: 'a,
134 T: 'a;
135
136 type WriteError<'a, T>
138 where
139 Self: 'a,
140 T: 'a;
141
142 fn new<T>(value: SharedValue<T>) -> Self::Storage<T>;
144 fn read<T>(
146 storage: &Self::Storage<T>,
147 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>>;
148 fn write<T>(
150 storage: &Self::Storage<T>,
151 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>>;
152}
153
154pub struct RefCellStorage;
156
157impl SharedStorage for RefCellStorage {
158 type Storage<T> = RefCell<SharedValue<T>>;
159 type ReadGuard<'a, T>
160 = Ref<'a, SharedValue<T>>
161 where
162 T: 'a;
163 type WriteGuard<'a, T>
164 = RefMut<'a, SharedValue<T>>
165 where
166 T: 'a;
167 type ReadError<'a, T>
168 = BorrowError
169 where
170 T: 'a;
171 type WriteError<'a, T>
172 = BorrowMutError
173 where
174 T: 'a;
175
176 fn new<T>(value: SharedValue<T>) -> Self::Storage<T> {
177 RefCell::new(value)
178 }
179
180 fn read<T>(
181 storage: &Self::Storage<T>,
182 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>> {
183 storage.try_borrow()
184 }
185
186 fn write<T>(
187 storage: &Self::Storage<T>,
188 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>> {
189 storage.try_borrow_mut()
190 }
191}
192
193pub struct MutexStorage;
195
196impl SharedStorage for MutexStorage {
197 type Storage<T> = Mutex<SharedValue<T>>;
198 type ReadGuard<'a, T>
199 = MutexGuard<'a, SharedValue<T>>
200 where
201 T: 'a;
202 type WriteGuard<'a, T>
203 = MutexGuard<'a, SharedValue<T>>
204 where
205 T: 'a;
206 type ReadError<'a, T>
207 = TryLockError<MutexGuard<'a, SharedValue<T>>>
208 where
209 T: 'a;
210 type WriteError<'a, T>
211 = TryLockError<MutexGuard<'a, SharedValue<T>>>
212 where
213 T: 'a;
214
215 fn new<T>(value: SharedValue<T>) -> Self::Storage<T> {
216 Mutex::new(value)
217 }
218
219 fn read<T>(
220 storage: &Self::Storage<T>,
221 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>> {
222 storage.try_lock()
223 }
224
225 fn write<T>(
226 storage: &Self::Storage<T>,
227 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>> {
228 storage.try_lock()
229 }
230}
231
232pub struct RwLockStorage;
234
235impl SharedStorage for RwLockStorage {
236 type Storage<T> = RwLock<SharedValue<T>>;
237 type ReadGuard<'a, T>
238 = RwLockReadGuard<'a, SharedValue<T>>
239 where
240 T: 'a;
241 type WriteGuard<'a, T>
242 = RwLockWriteGuard<'a, SharedValue<T>>
243 where
244 T: 'a;
245 type ReadError<'a, T>
246 = TryLockError<RwLockReadGuard<'a, SharedValue<T>>>
247 where
248 T: 'a;
249 type WriteError<'a, T>
250 = TryLockError<RwLockWriteGuard<'a, SharedValue<T>>>
251 where
252 T: 'a;
253
254 fn new<T>(value: SharedValue<T>) -> Self::Storage<T> {
255 RwLock::new(value)
256 }
257
258 fn read<T>(
259 storage: &Self::Storage<T>,
260 ) -> Result<Self::ReadGuard<'_, T>, Self::ReadError<'_, T>> {
261 storage.try_read()
262 }
263
264 fn write<T>(
265 storage: &Self::Storage<T>,
266 ) -> Result<Self::WriteGuard<'_, T>, Self::WriteError<'_, T>> {
267 storage.try_write()
268 }
269}