maybe_fut/api/sync/mutex/
guard.rs

1use std::fmt::Display;
2use std::ops::{Deref, DerefMut};
3
4/// An RAII implementation of a “scoped lck” of a mutex. When this structure is dropped (falls out of scope), the lock will be unlocked.
5///
6/// The data protected by the mutex can be accessed through this guard via its [`Deref`] and [`DerefMut`] implementations.
7///
8/// This structure is created by the [`super::Mutex::lock`] and [`super::Mutex::try_lock`] methods on [`super::Mutex`].
9#[derive(Debug)]
10pub struct MutexGuard<'a, T: ?Sized + 'a>(MutexGuardInner<'a, T>);
11
12#[derive(Debug)]
13enum MutexGuardInner<'a, T: ?Sized + 'a> {
14    /// Std mutex guard
15    Std(std::sync::MutexGuard<'a, T>),
16    /// Tokio mutex guard
17    #[cfg(tokio_sync)]
18    #[cfg_attr(docsrs, doc(cfg(feature = "tokio-sync")))]
19    Tokio(tokio::sync::MutexGuard<'a, T>),
20}
21
22impl<'a, T> From<std::sync::MutexGuard<'a, T>> for MutexGuard<'a, T> {
23    fn from(guard: std::sync::MutexGuard<'a, T>) -> Self {
24        MutexGuard(MutexGuardInner::Std(guard))
25    }
26}
27
28#[cfg(tokio_sync)]
29#[cfg_attr(docsrs, doc(cfg(feature = "tokio-sync")))]
30impl<'a, T> From<tokio::sync::MutexGuard<'a, T>> for MutexGuard<'a, T> {
31    fn from(guard: tokio::sync::MutexGuard<'a, T>) -> Self {
32        MutexGuard(MutexGuardInner::Tokio(guard))
33    }
34}
35
36impl<'a, T> Deref for MutexGuard<'a, T>
37where
38    T: ?Sized,
39{
40    type Target = T;
41
42    fn deref(&self) -> &Self::Target {
43        match &self.0 {
44            MutexGuardInner::Std(guard) => guard.deref(),
45            #[cfg(tokio_sync)]
46            MutexGuardInner::Tokio(guard) => guard.deref(),
47        }
48    }
49}
50
51impl<'a, T> DerefMut for MutexGuard<'a, T>
52where
53    T: ?Sized,
54{
55    fn deref_mut(&mut self) -> &mut Self::Target {
56        match &mut self.0 {
57            MutexGuardInner::Std(guard) => guard.deref_mut(),
58            #[cfg(tokio_sync)]
59            MutexGuardInner::Tokio(guard) => guard.deref_mut(),
60        }
61    }
62}
63
64impl Display for MutexGuard<'_, str> {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        match &self.0 {
67            MutexGuardInner::Std(guard) => guard.fmt(f),
68            #[cfg(tokio_sync)]
69            MutexGuardInner::Tokio(guard) => guard.fmt(f),
70        }
71    }
72}