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