use super::*;
use crate::{
cell::{Ref, RefMut, SingleThreadCell, SingleThreadError, SingleThreadMutError},
identity::Identity,
};
use std::{
cell::{LazyCell, OnceCell},
sync::{
LazyLock, MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard, Mutex, OnceLock, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard,
TryLockError,
},
};
mod rw;
pub use rw::*;
mod mutex;
pub use mutex::*;
mod cell;
pub use cell::*;
mod once_cell;
pub use once_cell::*;
mod once_lock;
pub use once_lock::*;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NotInitError;
impl Debug for NotInitError
{
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { f.write_str("Not init") }
}
pub mod prelude
{
pub(crate) use super::NotInitError;
pub use super::traits::*;
pub use super::{
SingletonCell, SingletonLazyCell, SingletonLazyMutex, SingletonLazyRw, SingletonMutex, SingletonOnce, SingletonOnceCell, SingletonOnceLazy,
SingletonOnceLazyCell, SingletonOptionCell, SingletonOptionMutex, SingletonOptionRw, SingletonRw,
};
}
pub mod traits
{
pub use super::{SingletonEmptyStruct, SingletonOnceable, SingletonOptionable};
}
pub struct SingletonOf<T>
{
pub(crate) guarded: T,
}
impl<T> SingletonOf<T>
{
pub const fn from_guard(guard: T) -> Self { Self { guarded: guard } }
}
impl<T> Deref for SingletonOf<T>
where
T: Deref,
{
type Target = T::Target;
#[inline(always)]
#[track_caller]
fn deref(&self) -> &Self::Target { self.guarded.deref() }
}
impl<T> DerefMut for SingletonOf<T>
where
T: DerefMut,
{
#[inline(always)]
#[track_caller]
fn deref_mut(&mut self) -> &mut Self::Target { self.guarded.deref_mut() }
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_singleton_methods {
($singleton_type:ident) => {
impl_singleton_methods_get!($singleton_type);
impl_singleton_methods_get_mut!($singleton_type);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_singleton_methods_get_mut {
($singleton_type:ident) => {
impl<T> $singleton_type<T>
{
#[track_caller]
#[inline]
pub fn get_mut<'a>(&'a self) -> <Self as GuardedMut<T>>::GuardMut<'a> { GuardedMut::get_mut(self) }
#[track_caller]
#[inline]
pub fn try_get_mut<'a>(&'a self) -> Result<<Self as GuardedMut<T>>::GuardMut<'a>, <Self as GuardedMut<T>>::Error<'a>>
{
GuardedMut::try_get_mut(self)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_singleton_methods_get {
($singleton_type:ident) => {
impl<T> $singleton_type<T>
{
#[track_caller]
#[inline]
pub fn get<'a>(&'a self) -> <Self as Guarded<T>>::Guard<'a> { Guarded::get(self) }
#[track_caller]
#[inline]
pub fn try_get<'a>(&'a self) -> Result<<Self as Guarded<T>>::Guard<'a>, <Self as Guarded<T>>::Error<'a>> { Guarded::try_get(self) }
}
};
}
pub trait SingletonOptionable<T>: GuardedMut<T>
{
fn init_from_fn<'a, F>(&'a self, init: F) -> Result<Self::GuardMut<'a>, F>
where
F: FnOnce() -> T;
fn swap<'a>(&'a self, other: &mut Option<T>) -> Result<(), Self::Error<'a>>;
fn init<'a>(&'a self, value: T) -> Result<Self::GuardMut<'a>, T>
{
match self.init_from_fn(|| value)
{
Ok(v) => Ok(v),
Err(init) => Err(init()),
}
}
fn replace<'a>(&'a self, mut value: Option<T>) -> Result<Option<T>, Self::Error<'a>>
{
self.swap(&mut value)?;
Ok(value)
}
fn take<'a>(&'a self) -> Result<Option<T>, Self::Error<'a>> { self.replace(None) }
fn reset<'a>(&'a self) -> Result<Option<T>, Self::Error<'a>> { self.take() }
}
pub trait SingletonOnceable<T>: Guarded<T>
{
fn init_from_fn<'a, F>(&'a self, init: F) -> Result<Self::Guard<'a>, F>
where
F: FnOnce() -> T;
fn init<'a>(&'a self, value: T) -> Result<Self::Guard<'a>, T>
{
match self.init_from_fn(|| value)
{
Ok(v) => Ok(v),
Err(init) => Err(init()),
}
}
}
pub trait SingletonEmptyStruct: Copy
{
fn is_init() -> bool;
fn is_not_init() -> bool { !Self::is_init() }
}