use core::{
borrow::{Borrow, BorrowMut},
ops::{Deref, DerefMut},
};
pub trait Tap<Ret>: Sized {
#[inline(always)]
fn tap(self, f: impl FnOnce(&Self) -> Ret) -> Self {
f(&self);
self
}
#[inline(always)]
fn tap_mut(mut self, f: impl FnOnce(&mut Self) -> Ret) -> Self {
f(&mut self);
self
}
#[inline(always)]
fn tap_borrow<B>(self, f: impl FnOnce(&B) -> Ret) -> Self
where
Self: Borrow<B>,
B: ?Sized,
{
f(Borrow::<B>::borrow(&self));
self
}
#[inline(always)]
fn tap_borrow_mut<B>(mut self, f: impl FnOnce(&mut B) -> Ret) -> Self
where
Self: BorrowMut<B>,
B: ?Sized,
{
f(BorrowMut::<B>::borrow_mut(&mut self));
self
}
#[inline(always)]
fn tap_as_ref<R>(self, f: impl FnOnce(&R) -> Ret) -> Self
where
Self: AsRef<R>,
R: ?Sized,
{
f(AsRef::<R>::as_ref(&self));
self
}
#[inline(always)]
fn tap_as_mut<R>(mut self, f: impl FnOnce(&mut R) -> Ret) -> Self
where
Self: AsMut<R>,
R: ?Sized,
{
f(AsMut::<R>::as_mut(&mut self));
self
}
#[inline(always)]
fn tap_deref<T>(self, f: impl FnOnce(&T) -> Ret) -> Self
where
Self: Deref<Target = T>,
T: ?Sized,
{
f(Deref::deref(&self));
self
}
#[inline(always)]
fn tap_deref_mut<T>(mut self, f: impl FnOnce(&mut T) -> Ret) -> Self
where
Self: DerefMut + Deref<Target = T>,
T: ?Sized,
{
f(DerefMut::deref_mut(&mut self));
self
}
#[inline(always)]
fn tap_dbg(self, f: impl FnOnce(&Self) -> Ret) -> Self {
if cfg!(debug_assertions) {
f(&self);
}
self
}
#[inline(always)]
fn tap_mut_dbg(mut self, f: impl FnOnce(&mut Self) -> Ret) -> Self {
if cfg!(debug_assertions) {
f(&mut self);
}
self
}
#[inline(always)]
fn tap_borrow_dbg<B>(self, f: impl FnOnce(&B) -> Ret) -> Self
where
Self: Borrow<B>,
B: ?Sized,
{
if cfg!(debug_assertions) {
f(Borrow::<B>::borrow(&self));
}
self
}
#[inline(always)]
fn tap_borrow_mut_dbg<B>(mut self, f: impl FnOnce(&mut B) -> Ret) -> Self
where
Self: BorrowMut<B>,
B: ?Sized,
{
if cfg!(debug_assertions) {
f(BorrowMut::<B>::borrow_mut(&mut self));
}
self
}
#[inline(always)]
fn tap_as_ref_dbg<R>(self, f: impl FnOnce(&R) -> Ret) -> Self
where
Self: AsRef<R>,
R: ?Sized,
{
if cfg!(debug_assertions) {
f(AsRef::<R>::as_ref(&self));
}
self
}
#[inline(always)]
fn tap_as_mut_dbg<R>(mut self, f: impl FnOnce(&mut R) -> Ret) -> Self
where
Self: AsMut<R>,
R: ?Sized,
{
if cfg!(debug_assertions) {
f(AsMut::<R>::as_mut(&mut self));
}
self
}
#[inline(always)]
fn tap_deref_dbg<T>(self, f: impl FnOnce(&T) -> Ret) -> Self
where
Self: Deref<Target = T>,
T: ?Sized,
{
if cfg!(debug_assertions) {
f(Deref::deref(&self));
}
self
}
#[inline(always)]
fn tap_deref_mut_dbg<T>(mut self, f: impl FnOnce(&mut T) -> Ret) -> Self
where
Self: DerefMut + Deref<Target = T>,
T: ?Sized,
{
if cfg!(debug_assertions) {
f(DerefMut::deref_mut(&mut self));
}
self
}
}
impl<T, R> Tap<R> for T {}
pub trait TapOptional<R>: Sized {
type Val: ?Sized;
fn tap_some(self, f: impl FnOnce(&Self::Val) -> R) -> Self;
fn tap_some_mut(self, f: impl FnOnce(&mut Self::Val) -> R) -> Self;
fn tap_none(self, f: impl FnOnce() -> R) -> Self;
#[inline(always)]
fn tap_some_dbg(self, f: impl FnOnce(&Self::Val) -> R) -> Self {
if cfg!(debug_assertions) {
self.tap_some(f)
} else {
self
}
}
#[inline(always)]
fn tap_some_mut_dbg(self, f: impl FnOnce(&mut Self::Val) -> R) -> Self {
if cfg!(debug_assertions) {
self.tap_some_mut(f)
} else {
self
}
}
#[inline(always)]
fn tap_none_dbg(self, f: impl FnOnce() -> R) -> Self {
if cfg!(debug_assertions) {
self.tap_none(f)
} else {
self
}
}
}
impl<T, R> TapOptional<R> for Option<T> {
type Val = T;
#[inline(always)]
fn tap_some(self, f: impl FnOnce(&T) -> R) -> Self {
if let Some(ref x) = self {
f(x);
}
self
}
#[inline(always)]
fn tap_some_mut(mut self, f: impl FnOnce(&mut T) -> R) -> Self {
if let Some(ref mut x) = self {
f(x);
}
self
}
#[inline(always)]
fn tap_none(self, f: impl FnOnce() -> R) -> Self {
if self.is_none() {
f();
}
self
}
}
pub trait TapFallible<R>: Sized {
type Ok: ?Sized;
type Err: ?Sized;
fn tap_ok(self, f: impl FnOnce(&Self::Ok) -> R) -> Self;
fn tap_ok_mut(self, f: impl FnOnce(&mut Self::Ok) -> R) -> Self;
fn tap_err(self, f: impl FnOnce(&Self::Err) -> R) -> Self;
fn tap_err_mut(self, f: impl FnOnce(&mut Self::Err) -> R) -> Self;
#[inline(always)]
fn tap_ok_dbg(self, f: impl FnOnce(&Self::Ok) -> R) -> Self {
if cfg!(debug_assertions) {
self.tap_ok(f)
} else {
self
}
}
#[inline(always)]
fn tap_ok_mut_dbg(self, f: impl FnOnce(&mut Self::Ok) -> R) -> Self {
if cfg!(debug_assertions) {
self.tap_ok_mut(f)
} else {
self
}
}
#[inline(always)]
fn tap_err_dbg(self, f: impl FnOnce(&Self::Err) -> R) -> Self {
if cfg!(debug_assertions) {
self.tap_err(f)
} else {
self
}
}
#[inline(always)]
fn tap_err_mut_dbg(self, f: impl FnOnce(&mut Self::Err) -> R) -> Self {
if cfg!(debug_assertions) {
self.tap_err_mut(f)
} else {
self
}
}
}
impl<T, E, R> TapFallible<R> for Result<T, E> {
type Ok = T;
type Err = E;
#[inline(always)]
fn tap_ok(self, f: impl FnOnce(&T) -> R) -> Self {
if let Ok(ref x) = self {
f(x);
}
self
}
#[inline(always)]
fn tap_ok_mut(mut self, f: impl FnOnce(&mut T) -> R) -> Self {
if let Ok(ref mut x) = self {
f(x);
}
self
}
#[inline(always)]
fn tap_err(self, f: impl FnOnce(&E) -> R) -> Self {
if let Err(ref x) = self {
f(x);
}
self
}
#[inline(always)]
fn tap_err_mut(mut self, f: impl FnOnce(&mut E) -> R) -> Self {
if let Err(ref mut x) = self {
f(x);
}
self
}
}