rskit_messaging/middleware/stack.rs
1//! Middleware stack builder for composing consumer handler pipelines.
2//!
3//! [`StackBuilder`] provides a fluent API to configure middleware and build
4//! a fully-wrapped handler in a standard order.
5//!
6//! # Example
7//!
8//! ```rust,ignore
9//! use rskit_messaging::middleware::StackBuilder;
10//!
11//! let handler = StackBuilder::<Vec<u8>>::new(base_handler)
12//! .with_retry(retry_config)
13//! .with_metrics(metrics, "my-topic")
14//! .build();
15//! ```
16
17use std::sync::Arc;
18
19use crate::handler::{HandlerMiddleware, MessageHandler, chain_handlers};
20
21/// Fluent builder for composing messaging middleware into a handler pipeline.
22///
23/// Middleware is applied in the order added — the first middleware added
24/// becomes the outermost wrapper and runs first on each message.
25///
26/// # Example
27///
28/// ```rust,ignore
29/// let stack = StackBuilder::new(base_handler)
30/// .with(retry_mw)
31/// .with(metrics_mw)
32/// .with(dedup_mw)
33/// .build();
34/// ```
35pub struct StackBuilder<T: Send + Sync + Clone + 'static> {
36 base: Arc<dyn MessageHandler<T>>,
37 middlewares: Vec<Arc<dyn HandlerMiddleware<T>>>,
38}
39
40impl<T: Send + Sync + Clone + 'static> StackBuilder<T> {
41 /// Create a new builder wrapping the given base handler.
42 pub fn new(base: Arc<dyn MessageHandler<T>>) -> Self {
43 Self {
44 base,
45 middlewares: Vec::new(),
46 }
47 }
48
49 /// Add middleware to the stack.
50 ///
51 /// Middleware is applied in the order added — the first middleware
52 /// added becomes the outermost wrapper.
53 #[must_use]
54 pub fn with<M: HandlerMiddleware<T> + 'static>(mut self, mw: M) -> Self {
55 self.middlewares.push(Arc::new(mw));
56 self
57 }
58
59 /// Build the fully-wrapped handler by applying all middleware.
60 pub fn build(self) -> Arc<dyn MessageHandler<T>> {
61 chain_handlers(self.base, &self.middlewares)
62 }
63}