use core::marker::PhantomData;
use crate::access::Access;
pub trait Extract<A: Access<T>, T>: Access<T> + Sized + TryExtract<A, T> {
fn extract(self) -> (A, <A as Access<T>>::RemainderFrom<Self>);
}
pub trait TryExtract<A: Access<T>, T>: Access<T> + Sized {
fn try_extract(self) -> Result<(A, <A as Access<T>>::RemainderFrom<Self>), Self>;
}
impl<T, A: Access<T>> Extract<PhantomData<T>, T> for A
where
Self: TryExtract<PhantomData<T>, T>,
{
fn extract(
self,
) -> (
PhantomData<T>,
<PhantomData<T> as Access<T>>::RemainderFrom<Self>,
) {
(PhantomData, self)
}
}
impl<T, A: Access<T>> Extract<Option<T>, T> for A
where
Self: TryExtract<Option<T>, T>,
{
fn extract(self) -> (Option<T>, <Option<T> as Access<T>>::RemainderFrom<Self>) {
(self.into_option(), PhantomData)
}
}
impl<T> Extract<T, T> for T {
fn extract(self) -> (T, <T as Access<T>>::RemainderFrom<Self>) {
(self, PhantomData)
}
}
impl<T, A: Access<T>> TryExtract<A, T> for Option<T> {
fn try_extract(self) -> Result<(A, <A as Access<T>>::RemainderFrom<Self>), Self> {
A::try_from_option(self)
}
}
impl<T, A: Access<T>> TryExtract<A, T> for T {
fn try_extract(self) -> Result<(A, <A as Access<T>>::RemainderFrom<Self>), Self> {
Ok(A::from_value(self))
}
}
impl<T> TryExtract<Option<T>, T> for PhantomData<T> {
fn try_extract(
self,
) -> Result<(Option<T>, <Option<T> as Access<T>>::RemainderFrom<Self>), Self> {
Ok((None, self))
}
}
impl<T> TryExtract<PhantomData<T>, T> for PhantomData<T> {
fn try_extract(
self,
) -> Result<
(
PhantomData<T>,
<PhantomData<T> as Access<T>>::RemainderFrom<Self>,
),
Self,
> {
Ok((PhantomData, self))
}
}