Skip to main content

qubit_function/consumers/consumer/
fn_consumer_ops.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `FnConsumerOps` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// ============================================================================
16// 6. Provide extension methods for closures
17// ============================================================================
18
19/// Extension trait providing non-mutating consumer composition methods for closures
20///
21/// Provides `and_then` and other composition methods for all closures
22/// implementing `Fn(&T)`, allowing closures to directly chain methods without
23/// explicit wrapper types.
24///
25/// # Features
26///
27/// - **Natural Syntax**: Chain operations directly on closures
28/// - **Returns BoxConsumer**: Combined results can continue chaining
29/// - **Zero Cost**: No overhead when composing closures
30/// - **Auto-implementation**: All `Fn(&T)` closures automatically get these
31///   methods
32///
33/// # Examples
34///
35/// ```rust
36/// use qubit_function::{Consumer, FnConsumerOps};
37///
38/// let chained = (|x: &i32| {
39///     println!("First: {}", x);
40/// }).and_then(|x: &i32| {
41///     println!("Second: {}", x);
42/// });
43/// chained.accept(&5);
44/// ```
45///
46/// # Author
47///
48/// Haixing Hu
49pub trait FnConsumerOps<T>: Fn(&T) + Sized {
50    /// Sequentially chain another non-mutating consumer
51    ///
52    /// Returns a new consumer that executes the current operation first, then the
53    /// next operation. Consumes the current closure and returns
54    /// `BoxConsumer<T>`.
55    ///
56    /// # Type Parameters
57    ///
58    /// * `C` - Type of the next consumer
59    ///
60    /// # Parameters
61    ///
62    /// * `next` - Consumer to execute after the current operation
63    ///
64    /// # Returns
65    ///
66    /// Returns a combined `BoxConsumer<T>`
67    ///
68    /// # Examples
69    ///
70    /// ```rust
71    /// use qubit_function::{Consumer, FnConsumerOps};
72    ///
73    /// let chained = (|x: &i32| {
74    ///     println!("First: {}", x);
75    /// }).and_then(|x: &i32| {
76    ///     println!("Second: {}", x);
77    /// }).and_then(|x: &i32| println!("Third: {}", x));
78    ///
79    /// chained.accept(&5);
80    /// ```
81    fn and_then<C>(self, next: C) -> BoxConsumer<T>
82    where
83        Self: 'static,
84        C: Consumer<T> + 'static,
85        T: 'static,
86    {
87        let first = self;
88        let second = next;
89        BoxConsumer::new(move |t| {
90            first(t);
91            second.accept(t);
92        })
93    }
94}
95
96/// Implement FnConsumerOps for all closure types
97impl<T, F> FnConsumerOps<T> for F where F: Fn(&T) {}