pub trait CallChain<S: ?Sized = Self> {
fn chain<R, F: FnOnce(&S) -> R>(&self, f: F) -> CallChainResult<'_, S, R>;
}
pub trait CallChainMut<S: ?Sized = Self> {
fn chain_mut<R, F: FnOnce(&mut S) -> R>(&mut self, f: F) -> CallChainResultMut<'_, S, R>;
}
impl<T: ?Sized> CallChain for T {
#[inline]
default fn chain<R, F: FnOnce(&T) -> R>(&self, f: F) -> CallChainResult<'_, T, R> {
CallChainResult {
result: f(self),
this: self
}
}
}
impl<T: ?Sized> CallChainMut for T {
#[inline]
default fn chain_mut<R, F: FnOnce(&mut T) -> R>(&mut self, f: F) -> CallChainResultMut<'_, T, R> {
CallChainResultMut {
result: f(self),
this: self
}
}
}
pub struct CallChainResult<'a, S: ?Sized, R> {
this: &'a S,
pub result: R
}
impl<S: ?Sized, R> CallChainResult<'_, S, R> {
#[inline]
pub fn into_result(self) -> R {
self.result
}
}
impl<S: ?Sized, R> AsRef<S> for CallChainResult<'_, S, R> {
#[inline]
fn as_ref(&self) -> &S {
self.this
}
}
impl<S: ?Sized, T> CallChain<S> for CallChainResult<'_, S, T> {
#[inline]
fn chain<R, F: FnOnce(&S) -> R>(&self, f: F) -> CallChainResult<'_, S, R> {
CallChainResult {
result: f(self.this),
this: self.this
}
}
}
impl<S: ?Sized, R> core::ops::Deref for CallChainResult<'_, S, R> {
type Target = R;
#[inline]
fn deref(&self) -> &R {
&self.result
}
}
impl<S: ?Sized, R> core::ops::DerefMut for CallChainResult<'_, S, R> {
#[inline]
fn deref_mut(&mut self) -> &mut R {
&mut self.result
}
}
pub struct CallChainResultMut<'a, S: ?Sized, R> {
this: &'a mut S,
pub result: R
}
impl<S: ?Sized, R> CallChainResultMut<'_, S, R> {
#[inline]
pub fn into_result(self) -> R {
self.result
}
}
impl<S: ?Sized, R> AsRef<S> for CallChainResultMut<'_, S, R> {
#[inline]
fn as_ref(&self) -> &S {
self.this
}
}
impl<S: ?Sized, R> AsMut<S> for CallChainResultMut<'_, S, R> {
#[inline]
fn as_mut(&mut self) -> &mut S {
self.this
}
}
impl<S: ?Sized, T> CallChain<S> for CallChainResultMut<'_, S, T> {
#[inline]
fn chain<R, F: FnOnce(&S) -> R>(&self, f: F) -> CallChainResult<'_, S, R> {
CallChainResult {
result: f(self.this),
this: self.this
}
}
}
impl<S: ?Sized, T> CallChainMut<S> for CallChainResultMut<'_, S, T> {
#[inline]
fn chain_mut<R, F: FnOnce(&mut S) -> R>(&mut self, f: F) -> CallChainResultMut<'_, S, R> {
CallChainResultMut {
result: f(self.this),
this: self.this
}
}
}
impl<S: ?Sized, R> core::ops::Deref for CallChainResultMut<'_, S, R> {
type Target = R;
#[inline]
fn deref(&self) -> &R {
&self.result
}
}
impl<S: ?Sized, R> core::ops::DerefMut for CallChainResultMut<'_, S, R> {
#[inline]
fn deref_mut(&mut self) -> &mut R {
&mut self.result
}
}