use core::marker::PhantomData;
use crate::presence::InferPresence;
pub trait Access<T>: InferPresence<T> {
const IS_ABSENT: bool;
type RemainderFrom<Source: Access<T>>: Access<T>;
fn get(&self) -> Option<&T>;
fn get_mut(&mut self) -> Option<&mut T>;
fn into_option(self) -> Option<T>;
fn from_value(value: T) -> (Self, Self::RemainderFrom<T>)
where
Self: Sized;
#[allow(clippy::type_complexity)]
fn try_from_option(
value: Option<T>,
) -> Result<(Self, Self::RemainderFrom<Option<T>>), Option<T>>
where
Self: Sized;
}
pub fn is_absent<A: Access<T>, T>(_value: &A) -> bool {
A::IS_ABSENT
}
impl<T> Access<T> for PhantomData<T> {
const IS_ABSENT: bool = true;
type RemainderFrom<Source: Access<T>> = Source;
#[inline]
fn get(&self) -> Option<&T> {
None
}
#[inline]
fn get_mut(&mut self) -> Option<&mut T> {
None
}
#[inline]
fn into_option(self) -> Option<T> {
None
}
#[inline]
fn from_value(value: T) -> (Self, Self::RemainderFrom<T>) {
(PhantomData, value)
}
#[inline]
fn try_from_option(
value: Option<T>,
) -> Result<(Self, Self::RemainderFrom<Option<T>>), Option<T>> {
Ok((PhantomData, value))
}
}
impl<T: Sized> Access<T> for T {
const IS_ABSENT: bool = false;
type RemainderFrom<Source: Access<T>> = PhantomData<T>;
#[inline]
fn get(&self) -> Option<&T> {
Some(self)
}
#[inline]
fn get_mut(&mut self) -> Option<&mut T> {
Some(self)
}
#[inline]
fn into_option(self) -> Option<T> {
Some(self)
}
#[inline]
fn from_value(value: T) -> (Self, Self::RemainderFrom<T>) {
(value, PhantomData)
}
#[inline]
fn try_from_option(
value: Option<T>,
) -> Result<(Self, Self::RemainderFrom<Option<T>>), Option<T>> {
match value {
Some(v) => Ok((v, PhantomData)),
None => Err(None),
}
}
}
impl<T> Access<T> for Option<T> {
const IS_ABSENT: bool = false;
type RemainderFrom<Source: Access<T>> = PhantomData<T>;
#[inline]
fn get(&self) -> Option<&T> {
self.as_ref()
}
#[inline]
fn get_mut(&mut self) -> Option<&mut T> {
self.as_mut()
}
#[inline]
fn into_option(self) -> Option<T> {
self
}
#[inline]
fn from_value(value: T) -> (Self, Self::RemainderFrom<T>) {
(Some(value), PhantomData)
}
#[inline]
fn try_from_option(
value: Option<T>,
) -> Result<(Self, Self::RemainderFrom<Option<T>>), Option<T>> {
Ok((value, PhantomData))
}
}