use crate::misc::Arc;
use alloc::rc::Rc;
use core::{future::Future, ops::DerefMut};
pub trait Lock {
type Guard<'guard>: DerefMut<Target = Self::Resource>
where
Self: 'guard;
type Resource;
fn new(resource: Self::Resource) -> Self;
fn lock(&self) -> impl Future<Output = Self::Guard<'_>>;
}
impl<T> Lock for Arc<T>
where
T: Lock,
{
type Guard<'guard>
= T::Guard<'guard>
where
Self: 'guard;
type Resource = T::Resource;
#[inline]
fn new(resource: Self::Resource) -> Self {
Arc::new(T::new(resource))
}
#[inline]
async fn lock(&self) -> Self::Guard<'_> {
(**self).lock().await
}
}
impl<T> Lock for Rc<T>
where
T: Lock,
{
type Guard<'guard>
= T::Guard<'guard>
where
Self: 'guard;
type Resource = T::Resource;
#[inline]
fn new(resource: Self::Resource) -> Self {
Rc::new(T::new(resource))
}
#[inline]
async fn lock(&self) -> Self::Guard<'_> {
(**self).lock().await
}
}
#[cfg(feature = "tokio")]
mod tokio {
use crate::misc::Lock;
use tokio::sync::{Mutex, MutexGuard};
impl<T> Lock for Mutex<T> {
type Guard<'guard>
= MutexGuard<'guard, Self::Resource>
where
Self: 'guard;
type Resource = T;
#[inline]
fn new(resource: Self::Resource) -> Self {
Mutex::new(resource)
}
#[inline]
async fn lock(&self) -> Self::Guard<'_> {
(*self).lock().await
}
}
}