qubit_function/consumers/bi_consumer/fn_bi_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 `FnBiConsumerOps` 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 bi-consumer composition methods for
20/// closures
21///
22/// Provides `and_then` and other composition methods for all closures
23/// implementing `Fn(&T, &U)`, enabling direct method chaining on closures
24/// without explicit wrapper types.
25///
26/// # Features
27///
28/// - **Natural Syntax**: Chain operations directly on closures
29/// - **Returns BoxBiConsumer**: Composition results can be
30/// further chained
31/// - **Zero Cost**: No overhead when composing closures
32/// - **Automatic Implementation**: All `Fn(&T, &U)` closures get these
33/// methods automatically
34///
35/// # Examples
36///
37/// ```rust
38/// use qubit_function::{BiConsumer, FnBiConsumerOps};
39///
40/// let chained = (|x: &i32, y: &i32| {
41/// println!("First: {}, {}", x, y);
42/// }).and_then(|x: &i32, y: &i32| {
43/// println!("Second: sum = {}", x + y);
44/// });
45/// chained.accept(&5, &3);
46/// ```
47///
48/// # Author
49///
50/// Haixing Hu
51pub trait FnBiConsumerOps<T, U>: Fn(&T, &U) + Sized {
52 /// Chains another non-mutating bi-consumer in sequence
53 ///
54 /// Returns a new consumer executing the current operation first, then
55 /// the next operation. Consumes the current closure and returns
56 /// `BoxBiConsumer<T, U>`.
57 ///
58 /// # Type Parameters
59 ///
60 /// * `C` - The type of the next consumer
61 ///
62 /// # Parameters
63 ///
64 /// * `next` - The consumer to execute after the current operation
65 ///
66 /// # Returns
67 ///
68 /// Returns the composed `BoxBiConsumer<T, U>`
69 ///
70 /// # Examples
71 ///
72 /// ```rust
73 /// use qubit_function::{BiConsumer, FnBiConsumerOps};
74 ///
75 /// let chained = (|x: &i32, y: &i32| {
76 /// println!("First: {}, {}", x, y);
77 /// }).and_then(|x: &i32, y: &i32| {
78 /// println!("Second: sum = {}", x + y);
79 /// }).and_then(|x: &i32, y: &i32| {
80 /// println!("Third: product = {}", x * y);
81 /// });
82 ///
83 /// chained.accept(&5, &3);
84 /// ```
85 fn and_then<C>(self, next: C) -> BoxBiConsumer<T, U>
86 where
87 Self: 'static,
88 C: BiConsumer<T, U> + 'static,
89 T: 'static,
90 U: 'static,
91 {
92 let first = self;
93 let second = next;
94 BoxBiConsumer::new(move |t, u| {
95 first(t, u);
96 second.accept(t, u);
97 })
98 }
99}
100
101/// Implements FnBiConsumerOps for all closure types
102impl<T, U, F> FnBiConsumerOps<T, U> for F where F: Fn(&T, &U) {}