pub trait HandlerExt<I, O, Args>: Handler<I, O, Args> {
// Provided methods
fn pipe(self) -> Pipe<Self, Args>
where Self: Sized { ... }
fn connect<O2, G, Args2>(
self,
g: G,
) -> Connect<Pipe<Self, Args>, Pipe<G, Args2>, I, O, O2>
where G: Handler<O, O2, Args2>,
Self: Sized { ... }
fn pullback<I2, H, Args2>(
self,
handler: H,
) -> Pullback<Pipe<Self, Args>, Pipe<H, Args2>, I2, I, O>
where H: Handler<I2, I, Args2>,
Self: Sized { ... }
fn lift<I2>(
self,
) -> Pullback<Pipe<Self, Args>, Pipe<LiftHandler<I, I2>, (Input<I2>,)>, I2, I, O>
where I: From<I2> + Send + Sync + 'static,
I2: Clone + Send + Sync + 'static,
Self: Sized { ... }
fn extend<O2, F>(self, map: F) -> Extend<Pipe<Self, Args>, F, I, O, O2>
where F: Fn(O) -> O2 + Send + Sync + 'static,
Self: Sized { ... }
fn repeat(self, times: usize) -> Repeat<Pipe<Self, Args>, I>
where Self: Handler<I, I, Args> + Sized,
I: Clone + Send + Sync + 'static { ... }
fn map(self) -> Map<Pipe<Self, Args>, I, O>
where Self: Sized { ... }
}Expand description
Extension trait for any type that implements the Handler trait. Provides a way to convert a Handler into a Pipeline and combinators.
Provided Methods§
fn pipe(self) -> Pipe<Self, Args>where
Self: Sized,
Sourcefn connect<O2, G, Args2>(
self,
g: G,
) -> Connect<Pipe<Self, Args>, Pipe<G, Args2>, I, O, O2>
fn connect<O2, G, Args2>( self, g: G, ) -> Connect<Pipe<Self, Args>, Pipe<G, Args2>, I, O, O2>
Connects two pipelines together. Output of the first becomes the input of the second.
§Example
use pipe_it::{Context, Pipeline, Input, ext::HandlerExt};
async fn add_one(n: Input<i32>) -> i32 { *n + 1 }
async fn to_string(n: Input<i32>) -> String { n.to_string() }
let pipe = add_one.pipe().connect(to_string);
let result = pipe.apply(Context::empty(1)).await;
assert_eq!(result, "2");Sourcefn pullback<I2, H, Args2>(
self,
handler: H,
) -> Pullback<Pipe<Self, Args>, Pipe<H, Args2>, I2, I, O>
fn pullback<I2, H, Args2>( self, handler: H, ) -> Pullback<Pipe<Self, Args>, Pipe<H, Args2>, I2, I, O>
Pulls back the domain of the pipeline.
This allows a pipeline defined on I to be used for input I2 given a mapping I2 -> I.
The mapping function is now a full Handler (async, supports DI).
§Example
use pipe_it::{Context, Pipeline, Input, ext::HandlerExt};
#[derive(Clone)]
struct User { age: i32 }
// Pre-processing step: extract age from User.
// Supports DI and ownership extraction.
async fn get_age(user: Input<User>) -> i32 {
// We can try_unwrap to get ownership if needed (optimization)
user.try_unwrap().map(|u| u.age).unwrap_or_else(|u| u.age)
}
async fn check_adult(age: Input<i32>) -> bool { *age >= 18 }
// Input: User -> (get_age) -> i32 -> (check_adult) -> bool
let pipe = check_adult.pipe().pullback(get_age);
let result = pipe.apply(Context::empty(User { age: 20 })).await;
assert_eq!(result, true);Sourcefn lift<I2>(
self,
) -> Pullback<Pipe<Self, Args>, Pipe<LiftHandler<I, I2>, (Input<I2>,)>, I2, I, O>
fn lift<I2>( self, ) -> Pullback<Pipe<Self, Args>, Pipe<LiftHandler<I, I2>, (Input<I2>,)>, I2, I, O>
Lifts the domain requirement to anything that can be converted into the original input.
Uses From / Into trait.
§Example
use pipe_it::{Context, Pipeline, Input, ext::HandlerExt};
async fn process_string(s: Input<String>) -> usize { s.len() }
// Accepts &str because String implements From<&str>
let pipe = process_string.pipe().lift::<&str>();
let result = pipe.apply(Context::empty("hello")).await;
assert_eq!(result, 5);Sourcefn extend<O2, F>(self, map: F) -> Extend<Pipe<Self, Args>, F, I, O, O2>
fn extend<O2, F>(self, map: F) -> Extend<Pipe<Self, Args>, F, I, O, O2>
Extends the output of the pipeline by applying a transformation.
§Example
use pipe_it::{Context, Pipeline, Input, ext::HandlerExt};
async fn compute(n: Input<i32>) -> i32 { *n * 2 }
// Changes output from i32 to String
let pipe = compute.pipe().extend(|n| format!("Result: {}", n));
let result = pipe.apply(Context::empty(10)).await;
assert_eq!(result, "Result: 20");Sourcefn repeat(self, times: usize) -> Repeat<Pipe<Self, Args>, I>
fn repeat(self, times: usize) -> Repeat<Pipe<Self, Args>, I>
Repeats the pipeline operation n times. Input and output types must be the same.
§Example
use pipe_it::{Context, Pipeline, Input, ext::HandlerExt};
async fn add_one(n: Input<i32>) -> i32 { *n + 1 }
// Input: 0 -> 1 -> 2 -> 3
let pipe = add_one.pipe().repeat(3);
let result = pipe.apply(Context::empty(0)).await;
assert_eq!(result, 3);Sourcefn map(self) -> Map<Pipe<Self, Args>, I, O>where
Self: Sized,
fn map(self) -> Map<Pipe<Self, Args>, I, O>where
Self: Sized,
Maps the pipeline over a collection of inputs concurrently.
Input for the new pipeline will be Vec<I> and output will be Vec<O>.
§Example
use pipe_it::{Context, Pipeline, Input, ext::HandlerExt};
async fn process_item(n: Input<i32>) -> String { n.to_string() }
// Input: Vec<i32> -> Output: Vec<String>
let pipe = process_item.pipe().map();
let result = pipe.apply(Context::empty(vec![1, 2, 3])).await;
assert_eq!(result, vec!["1", "2", "3"]);Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.