use crate::{
LockBefore, LockFor, Locked, OwnedTupleWrapper, RwLockFor, TupleWrapper, UnlockedAccess,
};
use core::ops::Deref;
pub mod prelude {
pub use super::{LockedWrapperApi as _, LockedWrapperUnlockedApi as _};
}
pub trait LockedWrapper<T, L>
where
T: Deref,
{
type AtLockLevel<'l, M>: LockedWrapper<&'l T::Target, M>
where
M: 'l,
T: 'l;
type CastWrapper<X>: LockedWrapper<X, L>
where
X: Deref,
X::Target: Sized;
fn wrap<'l, M>(locked: Locked<&'l T::Target, M>) -> Self::AtLockLevel<'l, M>
where
M: 'l,
T: 'l;
fn wrap_cast<R: Deref>(locked: Locked<R, L>) -> Self::CastWrapper<R>
where
R::Target: Sized;
fn get_mut(&mut self) -> &mut Locked<T, L>;
fn get(&self) -> &Locked<T, L>;
}
impl<T, L> LockedWrapper<T, L> for Locked<T, L>
where
T: Deref,
T::Target: Sized,
{
type AtLockLevel<'l, M>
= Locked<&'l T::Target, M>
where
M: 'l,
T: 'l;
type CastWrapper<X>
= Locked<X, L>
where
X: Deref,
X::Target: Sized;
fn wrap<'l, M>(locked: Locked<&'l T::Target, M>) -> Self::AtLockLevel<'l, M>
where
M: 'l,
T: 'l,
{
locked
}
fn wrap_cast<R: Deref>(locked: Locked<R, L>) -> Self::CastWrapper<R>
where
R::Target: Sized,
{
locked
}
fn get_mut(&mut self) -> &mut Locked<T, L> {
self
}
fn get(&self) -> &Locked<T, L> {
self
}
}
pub trait LockedWrapperUnlockedApi<'a, T: 'a, L: 'a>: LockedWrapper<&'a T, L> {
fn unlocked_access<M>(&self) -> T::Guard<'a>
where
T: UnlockedAccess<M>,
{
self.get().unlocked_access::<M>()
}
fn unlocked_access_with<M, X>(&self, f: impl FnOnce(&'a T) -> &'a X) -> X::Guard<'a>
where
X: UnlockedAccess<M>,
{
self.get().unlocked_access_with::<M, X>(f)
}
}
impl<'a, O, T, L> LockedWrapperUnlockedApi<'a, T, L> for O
where
T: 'a,
L: 'a,
O: LockedWrapper<&'a T, L>,
{
}
pub trait LockedWrapperApi<T, L>: LockedWrapper<T, L>
where
T: Deref,
T::Target: Sized,
{
fn lock<'a, M>(&'a mut self) -> <T::Target as LockFor<M>>::Guard<'a>
where
T: 'a,
T::Target: LockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().lock::<M>()
}
fn lock_and<'a, M>(
&'a mut self,
) -> (<T::Target as LockFor<M>>::Guard<'a>, Self::AtLockLevel<'a, M>)
where
T::Target: LockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().lock_and::<M>();
(guard, Self::wrap(locked))
}
fn lock_with<'a, M, X>(&'a mut self, f: impl FnOnce(&T::Target) -> &X) -> X::Guard<'a>
where
T: 'a,
X: LockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().lock_with::<M, X>(f)
}
fn lock_with_and<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> (X::Guard<'a>, Self::AtLockLevel<'a, M>)
where
X: LockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().lock_with_and::<M, X>(f);
(guard, Self::wrap(locked))
}
fn read_lock<'a, M>(&'a mut self) -> <T::Target as RwLockFor<M>>::ReadGuard<'a>
where
T: 'a,
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().read_lock::<M>()
}
fn read_lock_and<'a, M>(
&'a mut self,
) -> (<T::Target as RwLockFor<M>>::ReadGuard<'a>, Self::AtLockLevel<'a, M>)
where
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().read_lock_and::<M>();
(guard, Self::wrap(locked))
}
fn read_lock_with<'a, M, X>(&'a mut self, f: impl FnOnce(&T::Target) -> &X) -> X::ReadGuard<'a>
where
T: 'a,
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().read_lock_with::<M, X>(f)
}
fn read_lock_with_and<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> (X::ReadGuard<'a>, Self::AtLockLevel<'a, M>)
where
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().read_lock_with_and::<M, X>(f);
(guard, Self::wrap(locked))
}
fn write_lock<'a, M>(&'a mut self) -> <T::Target as RwLockFor<M>>::WriteGuard<'a>
where
T: 'a,
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().write_lock::<M>()
}
fn write_lock_and<'a, M>(
&'a mut self,
) -> (<T::Target as RwLockFor<M>>::WriteGuard<'a>, Self::AtLockLevel<'a, M>)
where
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().write_lock_and::<M>();
(guard, Self::wrap(locked))
}
fn write_lock_with<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> X::WriteGuard<'a>
where
T: 'a,
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().write_lock_with::<M, X>(f)
}
fn write_lock_with_and<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> (X::WriteGuard<'a>, Self::AtLockLevel<'a, M>)
where
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().write_lock_with_and::<M, X>(f);
(guard, Self::wrap(locked))
}
fn as_owned(&mut self) -> Self::AtLockLevel<'_, L> {
Self::wrap(self.get_mut().cast_with(|s| s))
}
fn cast<'a, R>(&'a mut self) -> Self::CastWrapper<&'a R>
where
T: 'a,
L: 'a,
T::Target: AsRef<R>,
{
Self::wrap_cast(self.get_mut().cast_with(AsRef::as_ref))
}
fn cast_with<'a, R>(&'a mut self, f: impl FnOnce(&T::Target) -> &R) -> Self::CastWrapper<&'a R>
where
T: 'a,
L: 'a,
{
Self::wrap_cast(self.get_mut().cast_with::<R>(f))
}
fn cast_locked<'a, M>(&'a mut self) -> Self::AtLockLevel<'a, M>
where
L: LockBefore<M> + 'a,
{
Self::wrap(self.get_mut().cast_locked::<M>())
}
fn copied(&self) -> T::Target
where
T::Target: Copy,
{
self.get().copied()
}
fn adopt<'a, N>(
&'a mut self,
n: &'a N,
) -> Self::CastWrapper<OwnedTupleWrapper<&'a T::Target, &'a N>>
where
T: 'a,
L: 'a,
{
Self::wrap_cast(self.get_mut().adopt(n))
}
fn cast_left<'a, X, A: Deref + 'a, B: Deref + 'a, F: FnOnce(&A::Target) -> &X>(
&'a mut self,
f: F,
) -> Self::CastWrapper<OwnedTupleWrapper<&'a X, &'a B::Target>>
where
L: 'a,
T: Deref<Target = TupleWrapper<A, B>> + 'a,
{
Self::wrap_cast(self.get_mut().cast_left(f))
}
fn cast_right<'a, X, A: Deref + 'a, B: Deref + 'a, F: FnOnce(&B::Target) -> &X>(
&'a mut self,
f: F,
) -> Self::CastWrapper<OwnedTupleWrapper<&'a A::Target, &'a X>>
where
L: 'a,
T: Deref<Target = TupleWrapper<A, B>> + 'a,
{
Self::wrap_cast(self.get_mut().cast_right(f))
}
fn replace<'a, N>(&'a mut self, n: &'a N) -> Self::CastWrapper<&'a N>
where
L: 'a,
T: 'a,
{
Self::wrap_cast(self.get_mut().replace(n))
}
}
impl<T, L, O> LockedWrapperApi<T, L> for O
where
T: Deref,
T::Target: Sized,
O: LockedWrapper<T, L>,
{
}
pub mod disable {
use core::marker::PhantomData;
use core::ops::Deref;
use super::LockedWrapper;
use crate::{
LockBefore, LockFor, Locked, OwnedTupleWrapper, RwLockFor, TupleWrapper, Unlocked,
};
pub mod prelude {
pub use super::super::LockedWrapperUnlockedApi as _;
pub use super::LockedDisabledWrapperApi as _;
}
pub unsafe trait DisabledLockWrapper {}
fn disabled<T, L>(Locked(t, PhantomData): Locked<T, L>) -> Locked<T, Unlocked> {
Locked(t, PhantomData)
}
pub trait LockedDisabledWrapperApi<T, L>: LockedWrapper<T, L> + DisabledLockWrapper
where
T: Deref,
T::Target: Sized,
{
fn lock<'a, M>(&'a mut self) -> <T::Target as LockFor<M>>::Guard<'a>
where
T: 'a,
T::Target: LockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().lock::<M>()
}
fn lock_and<'a, M>(
&'a mut self,
) -> (<T::Target as LockFor<M>>::Guard<'a>, Self::AtLockLevel<'a, Unlocked>)
where
T::Target: LockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().lock_and::<M>();
(guard, Self::wrap(disabled(locked)))
}
fn lock_with<'a, M, X>(&'a mut self, f: impl FnOnce(&T::Target) -> &X) -> X::Guard<'a>
where
T: 'a,
X: LockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().lock_with::<M, X>(f)
}
fn lock_with_and<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> (X::Guard<'a>, Self::AtLockLevel<'a, Unlocked>)
where
X: LockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().lock_with_and::<M, X>(f);
(guard, Self::wrap(disabled(locked)))
}
fn read_lock<'a, M>(&'a mut self) -> <T::Target as RwLockFor<M>>::ReadGuard<'a>
where
T: 'a,
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().read_lock::<M>()
}
fn read_lock_and<'a, M>(
&'a mut self,
) -> (<T::Target as RwLockFor<M>>::ReadGuard<'a>, Self::AtLockLevel<'a, Unlocked>)
where
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().read_lock_and::<M>();
(guard, Self::wrap(disabled(locked)))
}
fn read_lock_with<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> X::ReadGuard<'a>
where
T: 'a,
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().read_lock_with::<M, X>(f)
}
fn read_lock_with_and<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> (X::ReadGuard<'a>, Self::AtLockLevel<'a, Unlocked>)
where
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().read_lock_with_and::<M, X>(f);
(guard, Self::wrap(disabled(locked)))
}
fn write_lock<'a, M>(&'a mut self) -> <T::Target as RwLockFor<M>>::WriteGuard<'a>
where
T: 'a,
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().write_lock::<M>()
}
fn write_lock_and<'a, M>(
&'a mut self,
) -> (<T::Target as RwLockFor<M>>::WriteGuard<'a>, Self::AtLockLevel<'a, Unlocked>)
where
T::Target: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().write_lock_and::<M>();
(guard, Self::wrap(disabled(locked)))
}
fn write_lock_with<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> X::WriteGuard<'a>
where
T: 'a,
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
self.get_mut().write_lock_with::<M, X>(f)
}
fn write_lock_with_and<'a, M, X>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &X,
) -> (X::WriteGuard<'a>, Self::AtLockLevel<'a, Unlocked>)
where
X: RwLockFor<M>,
L: LockBefore<M> + 'a,
{
let (guard, locked) = self.get_mut().write_lock_with_and::<M, X>(f);
(guard, Self::wrap(disabled(locked)))
}
fn as_owned(&mut self) -> Self::AtLockLevel<'_, L> {
Self::wrap(self.get_mut().cast_with(|s| s))
}
fn cast<'a, R>(&'a mut self) -> Self::CastWrapper<&'a R>
where
T: 'a,
L: 'a,
T::Target: AsRef<R>,
{
Self::wrap_cast(self.get_mut().cast_with(AsRef::as_ref))
}
fn cast_with<'a, R>(
&'a mut self,
f: impl FnOnce(&T::Target) -> &R,
) -> Self::CastWrapper<&'a R>
where
T: 'a,
L: 'a,
{
Self::wrap_cast(self.get_mut().cast_with::<R>(f))
}
fn cast_locked<'a, M>(&'a mut self) -> Self::AtLockLevel<'a, Unlocked>
where
L: LockBefore<M> + 'a,
{
Self::wrap(disabled(self.get_mut().cast_locked::<M>()))
}
fn copied(&self) -> T::Target
where
T::Target: Copy,
{
self.get().copied()
}
fn adopt<'a, N>(
&'a mut self,
n: &'a N,
) -> Self::CastWrapper<OwnedTupleWrapper<&'a T::Target, &'a N>>
where
T: 'a,
L: 'a,
{
Self::wrap_cast(self.get_mut().adopt(n))
}
fn cast_left<'a, X, A: Deref + 'a, B: Deref + 'a, F: FnOnce(&A::Target) -> &X>(
&'a mut self,
f: F,
) -> Self::CastWrapper<OwnedTupleWrapper<&'a X, &'a B::Target>>
where
L: 'a,
T: Deref<Target = TupleWrapper<A, B>> + 'a,
{
Self::wrap_cast(self.get_mut().cast_left(f))
}
fn cast_right<'a, X, A: Deref + 'a, B: Deref + 'a, F: FnOnce(&B::Target) -> &X>(
&'a mut self,
f: F,
) -> Self::CastWrapper<OwnedTupleWrapper<&'a A::Target, &'a X>>
where
L: 'a,
T: Deref<Target = TupleWrapper<A, B>> + 'a,
{
Self::wrap_cast(self.get_mut().cast_right(f))
}
fn replace<'a, N>(&'a mut self, n: &'a N) -> Self::CastWrapper<&'a N>
where
L: 'a,
T: 'a,
{
Self::wrap_cast(self.get_mut().replace(n))
}
}
impl<T, L, O> LockedDisabledWrapperApi<T, L> for O
where
T: Deref,
T::Target: Sized,
O: LockedWrapper<T, L> + DisabledLockWrapper,
{
}
}