Skip to main content

HandlerExt

Trait HandlerExt 

Source
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 { ... }
}
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§

Source

fn pipe(self) -> Pipe<Self, Args>
where Self: Sized,

Source

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,

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

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,

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

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,

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

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,

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

fn repeat(self, times: usize) -> Repeat<Pipe<Self, Args>, I>
where Self: Handler<I, I, Args> + Sized, I: Clone + Send + Sync + 'static,

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

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.

Implementors§

Source§

impl<F, I, O, Args> HandlerExt<I, O, Args> for F
where F: Handler<I, O, Args>,