Skip to main content

TapWith

Trait TapWith 

Source
pub trait TapWith<const ARITY: usize, State> {
    // Provided method
    fn tap_with<'a, R, F, P, Args>(self, proj: P, f: F) -> F::Curry<'a>
       where F: CurryWith<ARITY, Args, State, Self, P, R>,
             Self: Sized { ... }
}
Expand description

Extension trait for running side effects on a projection of the value.

Provided Methods§

Source

fn tap_with<'a, R, F, P, Args>(self, proj: P, f: F) -> F::Curry<'a>
where F: CurryWith<ARITY, Args, State, 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.

The projection can adapt the value in any way — accessing a field, calling .as_ref(), .as_bytes(), or any other transformation — bridging the gap when the side effect’s signature doesn’t match the receiver directly. This subsumes the specialized methods from the tap crate (tap_some, tap_ok, tap_err, tap_dbg, …) through a single generic projection.

§Examples
#[derive(Debug)]
struct Request { url: String, attempts: u32 }

fn assert_ascii(bytes: &[u8]) { assert!(bytes.is_ascii()); }
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".into(), attempts: 3 };

// project to bytes
(&req).tap_with(|r| Some(r.url.as_bytes()), assert_ascii)();

// project to a mutable field
(&mut req).tap_with(|r| Some(&mut r.attempts), track_retry)();
assert_eq!(req.attempts, 4);

// tap only on Err
let res = Err::<Request, _>(503)
    .tap_with(|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_with(|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