use std::future::Future;
use std::ops::Deref;
use std::ops::DerefMut;
use std::sync::Arc;
use crate::OptionalSend;
use crate::OptionalSync;
pub trait Mutex<T>: OptionalSend + OptionalSync + 'static
where T: OptionalSend + 'static
{
type Guard<'a>: DerefMut<Target = T> + OptionalSend
where Self: 'a;
#[track_caller]
fn new(value: T) -> Self;
#[track_caller]
fn lock(&self) -> impl Future<Output = Self::Guard<'_>> + OptionalSend;
#[must_use]
fn lock_owned(self: Arc<Self>) -> impl Future<Output = OwnedGuard<Self, T>> + OptionalSend
where Self: Sized {
async move {
let guard = self.lock().await;
let guard_static = unsafe { std::mem::transmute::<Self::Guard<'_>, Self::Guard<'static>>(guard) };
OwnedGuard {
guard: guard_static,
_mutex: self,
}
}
}
}
pub struct OwnedGuard<M, T>
where
M: Mutex<T>,
T: OptionalSend + 'static,
{
guard: M::Guard<'static>,
_mutex: Arc<M>,
}
impl<M, T> Deref for OwnedGuard<M, T>
where
M: Mutex<T>,
T: OptionalSend + 'static,
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.guard
}
}
impl<M, T> DerefMut for OwnedGuard<M, T>
where
M: Mutex<T>,
T: OptionalSend + 'static,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.guard
}
}