use crate::plug::*;
#[cfg(feature = "async")]
use std::future::Future;
use std::pin::Pin;
pub use locktree_derive::locktree;
pub mod plug;
pub type PluggedGuard<'a, T> = <T as PlugLifetime<'a>>::Type;
pub type PluggedMutexGuard<'a, T> = PluggedGuard<'a, <T as Mutex>::Guard>;
pub type PluggedRwLockReadGuard<'a, T> =
PluggedGuard<'a, <T as RwLock>::ReadGuard>;
pub type PluggedRwLockWriteGuard<'a, T> =
PluggedGuard<'a, <T as RwLock>::WriteGuard>;
#[cfg(feature = "async")]
pub type PluggedAsyncGuard<'a, T> =
Pin<Box<dyn Future<Output = <T as PlugLifetime<'a>>::Type> + 'a>>;
#[cfg(feature = "async")]
pub type PluggedAsyncMutexGuard<'a, T> =
PluggedAsyncGuard<'a, <T as AsyncMutex>::Guard>;
#[cfg(feature = "async")]
pub type PluggedAsyncRwLockReadGuard<'a, T> =
PluggedAsyncGuard<'a, <T as AsyncRwLock>::ReadGuard>;
#[cfg(feature = "async")]
pub type PluggedAsyncRwLockWriteGuard<'a, T> =
PluggedAsyncGuard<'a, <T as AsyncRwLock>::WriteGuard>;
pub trait New<T> {
fn new(value: T) -> Self;
}
impl<T> New<T> for ::std::sync::Mutex<T> {
fn new(value: T) -> Self {
Self::new(value)
}
}
impl<T> New<T> for ::std::sync::RwLock<T> {
fn new(value: T) -> Self {
Self::new(value)
}
}
#[cfg(feature = "tokio")]
impl<T> New<T> for ::tokio::sync::Mutex<T> {
fn new(value: T) -> Self {
Self::new(value)
}
}
#[cfg(feature = "tokio")]
impl<T> New<T> for ::tokio::sync::RwLock<T> {
fn new(value: T) -> Self {
Self::new(value)
}
}
pub trait Mutex {
type Guard: for<'a> PlugLifetime<'a>;
fn lock(&self) -> PluggedGuard<Self::Guard>;
}
impl<T> Mutex for std::sync::Mutex<T>
where
T: 'static,
{
type Guard = H1MutexLockGuard<T>;
fn lock(&self) -> PluggedGuard<Self::Guard> {
std::sync::Mutex::<T>::lock(self).unwrap()
}
}
#[cfg(feature = "async")]
pub trait AsyncMutex {
type Guard: for<'a> PlugLifetime<'a>;
fn lock(&self) -> PluggedAsyncGuard<Self::Guard>;
}
#[cfg(feature = "tokio")]
impl<T> AsyncMutex for tokio::sync::Mutex<T>
where
T: 'static,
{
type Guard = H1TokioMutexLockGuard<T>;
fn lock(&self) -> PluggedAsyncGuard<Self::Guard> {
Box::pin(tokio::sync::Mutex::<T>::lock(self))
}
}
pub trait RwLock {
type ReadGuard: for<'a> PlugLifetime<'a>;
type WriteGuard: for<'a> PlugLifetime<'a>;
fn read(&self) -> PluggedGuard<Self::ReadGuard>;
fn write(&self) -> PluggedGuard<Self::WriteGuard>;
}
impl<T> RwLock for std::sync::RwLock<T>
where
T: 'static,
{
type ReadGuard = H1RwLockReadGuard<T>;
type WriteGuard = H1RwLockWriteGuard<T>;
fn read(&self) -> PluggedGuard<Self::ReadGuard> {
std::sync::RwLock::<T>::read(self).unwrap()
}
fn write(&self) -> PluggedGuard<Self::WriteGuard> {
std::sync::RwLock::<T>::write(self).unwrap()
}
}
impl<T> RwLock for T
where
T: Mutex,
{
type ReadGuard = T::Guard;
type WriteGuard = T::Guard;
fn read(&self) -> PluggedGuard<Self::ReadGuard> {
self.lock()
}
fn write(&self) -> PluggedGuard<Self::WriteGuard> {
self.lock()
}
}
#[cfg(feature = "async")]
pub trait AsyncRwLock {
type ReadGuard: for<'a> PlugLifetime<'a>;
type WriteGuard: for<'a> PlugLifetime<'a>;
fn read(&self) -> PluggedAsyncGuard<Self::ReadGuard>;
fn write(&self) -> PluggedAsyncGuard<Self::WriteGuard>;
}
#[cfg(feature = "tokio")]
impl<T> AsyncRwLock for tokio::sync::RwLock<T>
where
T: 'static,
{
type ReadGuard = H1TokioRwLockReadGuard<T>;
type WriteGuard = H1TokioRwLockWriteGuard<T>;
fn read(&self) -> PluggedAsyncGuard<Self::ReadGuard> {
Box::pin(tokio::sync::RwLock::<T>::read(self))
}
fn write(&self) -> PluggedAsyncGuard<Self::WriteGuard> {
Box::pin(tokio::sync::RwLock::<T>::write(self))
}
}
#[cfg(feature = "async")]
impl<T> AsyncRwLock for T
where
T: AsyncMutex,
{
type ReadGuard = T::Guard;
type WriteGuard = T::Guard;
fn read(&self) -> PluggedAsyncGuard<Self::ReadGuard> {
self.lock()
}
fn write(&self) -> PluggedAsyncGuard<Self::WriteGuard> {
self.lock()
}
}