tap icon indicating copy to clipboard operation
tap copied to clipboard

add pipe_if method(s)

Open Zoybean opened this issue 2 years ago • 2 comments

Reading this comment on the rust internals forum got me interested in a conditional pipe method; to borrow the example from the post, it would simplify pipes with basic tests like this:

Builder::new()
    .foo()
    .bar()
    .pipe(|it| if bazable {
        it.baz()
    } else {
        it
    })
    .quux()
    .build()

Into this:

Builder::new()
    .foo()
    .bar()
    .pipe_if(bazable, |it| it.baz())
    .quux()
    .build()

I figure the implementations would be trivial, the main factor that I see getting in the way of this is that it could mean doubling the number of methods on Pipe, by adding _ref, _ref_mut, _deref etc variants.

Zoybean avatar Mar 20 '22 07:03 Zoybean

I think that would be great : )

ericsampson avatar Feb 17 '23 06:02 ericsampson

Also something like pipe_map:

Builder::new()
    .foo()
    .bar()
    .pipe(|it| if let Some(inner) = maybe_baz {
        it.baz(inner)
    } else {
        it
    })
    .quux()
    .build()

Builder::new()
    .foo()
    .bar()
    .pipe_map(maybe_baz, |it, inner| it.baz(inner))
    .quux()
    .build()

pub trait Pipe {
    ...

    #[inline(always)]
    fn pipe_map<O>(self, option: Option<O>, func: impl FnOnce(Self, O) -> Self) -> Self
    where
        Self: Sized,
        O: Sized,
    {
        if let Some(inner) = option {
            func(self, inner)
        } else {
            self
        }
    }
}

flying-sheep avatar Feb 23 '24 09:02 flying-sheep