Skip to main content

TapWith

Trait TapWith 

Source
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§

Source

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,

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);
Source

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,

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);

Implementors§

Source§

impl<const ARITY: usize, State, T> TapWith<ARITY, State> for T