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