use crate::{Mutex, MutexGuard}; use core::ops::{Deref, DerefMut}; enum Value { Full(T), Empty } pub struct StaticMutex { value: Mutex> } impl StaticMutex { pub const fn new() -> Self { Self { value: Mutex::new(Value::Empty) } } #[track_caller] pub async fn init(&self, new: T) { let mut value = self.value.lock().await; if !matches!(*value, Value::Empty) { panic!("Cannot initialise StaticMutex more than once"); } *value = Value::Full(new); } #[track_caller] pub async fn lock(&self) -> StaticMutexLockGuard<'_, T> { let inner = self.value.lock().await; if matches!(*inner, Value::Empty) { panic!("This StaticMutex has not been initialised yet"); } StaticMutexLockGuard { inner } } } pub struct StaticMutexLockGuard<'a, T> { inner: MutexGuard<'a, Value> } impl Deref for StaticMutexLockGuard<'_, T> { type Target = T; fn deref(&self) -> &Self::Target { match self.inner.deref() { Value::Full(ref value) => value, _ => unreachable!() } } } impl DerefMut for StaticMutexLockGuard<'_, T> { fn deref_mut(&mut self) -> &mut Self::Target { match self.inner.deref_mut() { Value::Full(ref mut value) => value, _ => unreachable!() } } }