pub trait TapWith<const ARITY: usize, State> {
// Provided methods
fn tap_proj<R, F, P, Args>(self, proj: P, f: F) -> F::Curry
where F: CurryWith<ARITY, Args, State, Proj, Self, P, R>,
Self: Sized { ... }
fn tap_cond<R, F, P, Args>(self, proj: P, f: F) -> F::Curry
where F: CurryWith<ARITY, Args, State, Cond, Self, P, R>,
Self: Sized { ... }
}Expand description
Extension trait for running side effects on a projection (conditional or unconditional) of the value.
Provided Methods§
Sourcefn tap_proj<R, F, P, Args>(self, proj: P, f: F) -> F::Currywhere
F: CurryWith<ARITY, Args, State, Proj, Self, P, R>,
Self: Sized,
fn tap_proj<R, F, P, Args>(self, proj: P, f: F) -> F::Currywhere
F: CurryWith<ARITY, Args, State, Proj, Self, P, R>,
Self: Sized,
Applies a projection to self, then runs f on the projected reference.
The projection returns &T or &mut T directly — it always runs.
The original value is returned.
§Examples
struct Pair { a: i32, b: i32 }
fn check(v: &i32) { assert!(*v > 0); }
fn increment(v: &mut i32) { *v += 1; }
let p = Pair { a: 1, b: 2 }
.tap_proj(|p: &Pair| &p.a, check)()
.tap_proj(|p| &mut p.b, increment)();
assert_eq!(p.b, 3);Sourcefn tap_cond<R, F, P, Args>(self, proj: P, f: F) -> F::Currywhere
F: CurryWith<ARITY, Args, State, Cond, Self, P, R>,
Self: Sized,
fn tap_cond<R, F, P, Args>(self, proj: P, f: F) -> F::Currywhere
F: CurryWith<ARITY, Args, State, Cond, Self, P, R>,
Self: Sized,
Runs a side effect on a projection of self. The projection returns
an Option; if Some, the side effect runs on the projected value.
If None, the side effect is skipped. In both cases, self is returned.
§Examples
#[derive(Debug)]
struct Request { url: String, attempts: u32 }
fn track_retry(count: &mut u32) { *count += 1 }
fn log_status(code: &u32, url: &str, count: u32) { eprintln!("{url}: error {code} (attempt {count})"); }
fn log_trace<T: core::fmt::Debug>(val: &T, label: &str) { eprintln!("{label}: {val:?}"); }
let mut req = Request { url: "[https://pipei.rs](https://pipei.rs)".into(), attempts: 3 };
// project to a mutable field
(&mut req).tap_cond(|r| Some(&mut r.attempts), track_retry)();
assert_eq!(req.attempts, 4);
// tap only on Err
let res = Err::<Request, _>(503)
.tap_cond(|x| x.as_ref().err(), log_status)(&req.url, req.attempts);
assert_eq!(res.unwrap_err(), 503);
// tap only in debug builds
let req = req.tap_cond(|r| {
#[cfg(debug_assertions)] { Some(r) }
#[cfg(not(debug_assertions))] { None }
}, log_trace)("FINAL");
assert_eq!(req.attempts, 4);