Pipeline

Struct Pipeline 

Source
pub struct Pipeline<R, W> { /* private fields */ }
Expand description

Pipeline traits for inbound and outbound message processing A pipeline of handlers for processing protocol messages.

The Pipeline is the main abstraction for building protocol stacks in sansio. It maintains an ordered chain of Handlers and routes messages bidirectionally through them.

§Type Parameters

  • R: Input type at the bottom of the pipeline (from network/transport)
  • W: Write type at the top of the pipeline (from application)

§Lifecycle

  1. Create: Pipeline::new()
  2. Build: Add handlers with add_back() or add_front()
  3. Finalize: Call finalize() to link handlers and wrap in Rc
  4. Use: Call methods from InboundPipeline and OutboundPipeline traits

§Example

use sansio::{Pipeline, Handler, Context, InboundPipeline};

// Create and build pipeline
let pipeline: Pipeline<String, String> = Pipeline::new();
pipeline.add_back(EchoHandler);

// Finalize before use
let pipeline = pipeline.finalize();

// Use the pipeline
pipeline.transport_active();
pipeline.handle_read("Hello".to_string());
if let Some(msg) = pipeline.poll_write() {
    println!("Got: {}", msg);
}

§Thread Safety

Pipelines use Rc (not Arc) and are not thread-safe. They are designed for single-threaded I/O loops. For multi-threaded usage, create separate pipelines per thread.

Implementations§

Source§

impl<R: 'static, W: 'static> Pipeline<R, W>

Source

pub fn new() -> Self

Creates a new empty pipeline.

The pipeline starts with no handlers. Use add_back or add_front to add handlers, then call finalize before using it.

§Example
use sansio::Pipeline;

let pipeline: Pipeline<Vec<u8>, String> = Pipeline::new();
Source

pub fn add_back(&self, handler: impl Handler + 'static) -> &Self

Appends a handler at the end of the pipeline.

Handlers are processed in the order they are added:

  • Inbound: first → last
  • Outbound: last → first

Returns &self for method chaining.

§Parameters
  • handler: The handler to append
§Example
let pipeline: Pipeline<String, String> = Pipeline::new();
pipeline
    .add_back(H1)  // First handler
    .add_back(H2); // Second handler
Source

pub fn add_front(&self, handler: impl Handler + 'static) -> &Self

Inserts a handler at the beginning of the pipeline.

The new handler will be the first to process inbound messages.

Returns &self for method chaining.

§Parameters
  • handler: The handler to prepend
§Example
let pipeline: Pipeline<String, String> = Pipeline::new();
pipeline.add_front(H1); // Will be first in chain
Source

pub fn remove_back(&self) -> Result<&Self, Error>

Removes the last handler from the pipeline.

§Returns
  • Ok(&self): Handler removed successfully (for chaining)
  • Err(io::Error): Pipeline is empty
§Example
let pipeline: Pipeline<String, String> = Pipeline::new();
pipeline.add_back(H1);
pipeline.remove_back().unwrap();
Source

pub fn remove_front(&self) -> Result<&Self, Error>

Removes the first handler from the pipeline.

§Returns
  • Ok(&self): Handler removed successfully (for chaining)
  • Err(io::Error): Pipeline is empty
Source

pub fn remove(&self, handler_name: &str) -> Result<&Self, Error>

Removes a specific handler by name.

Searches for a handler with the given name and removes it.

§Parameters
  • handler_name: The name of the handler to remove (from Handler::name)
§Returns
  • Ok(&self): Handler removed successfully (for chaining)
  • Err(io::Error): Handler not found
§Example
let pipeline: Pipeline<String, String> = Pipeline::new();
pipeline.add_back(MyHandler);
let pipeline = pipeline.finalize();

pipeline.remove("MyHandler").unwrap();
Source

pub fn len(&self) -> usize

Returns the number of handlers in the pipeline.

§Example
let pipeline: Pipeline<String, String> = Pipeline::new();
assert_eq!(pipeline.len(), 0);

pipeline.add_back(H1);
assert_eq!(pipeline.len(), 1);
Source

pub fn update(self: Rc<Self>) -> Rc<Self>

Updates an Rc-wrapped pipeline’s internal structure.

Called internally by finalize. You typically don’t need to call this directly.

Source

pub fn finalize(self) -> Rc<Self>

Finalizes the pipeline, making it ready for use.

This method:

  1. Wraps the pipeline in Rc for shared ownership
  2. Links handlers together internally
  3. Returns the finalized Rc<Pipeline>

You must call this before using the pipeline.

§Example
let pipeline: Pipeline<String, String> = Pipeline::new();
pipeline.add_back(H1);

// Finalize before use
let pipeline = pipeline.finalize();

// Now ready to use
pipeline.handle_read("Hello".to_string());

Trait Implementations§

Source§

impl<R: 'static, W: 'static> Default for Pipeline<R, W>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<R: 'static, W: 'static> InboundPipeline<R> for Pipeline<R, W>

Source§

fn transport_active(&self)

Transport is active now, which means it is connected.

Source§

fn transport_inactive(&self)

Transport is inactive now, which means it is disconnected.

Source§

fn handle_read(&self, msg: R)

Handles an incoming message.

Source§

fn poll_write(&self) -> Option<R>

Polls an outgoing message

Source§

fn handle_timeout(&self, now: Instant)

Handles a timeout event.

Source§

fn poll_timeout(&self, eto: &mut Instant)

Polls earliest timeout (eto) in its inbound operations.

Source§

fn handle_eof(&self)

Handles an EOF event.

Source§

fn handle_error(&self, err: Box<dyn Error>)

Handles an Error in one of its inbound operations.

Source§

impl<R: 'static, W: 'static> OutboundPipeline<W> for Pipeline<R, W>

Source§

fn write(&self, msg: W)

Writes a message to pipeline

Source§

fn close(&self)

Writes a close event.

Auto Trait Implementations§

§

impl<R, W> !Freeze for Pipeline<R, W>

§

impl<R, W> !RefUnwindSafe for Pipeline<R, W>

§

impl<R, W> !Send for Pipeline<R, W>

§

impl<R, W> !Sync for Pipeline<R, W>

§

impl<R, W> Unpin for Pipeline<R, W>
where R: Unpin,

§

impl<R, W> !UnwindSafe for Pipeline<R, W>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.