1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! # BiConsumer Types
//!
//! Provides bi-consumer interfaces for operations invoked through `&self` with
//! two shared input references. The API grants no direct mutable access to the
//! wrapper or inputs, but callbacks may use interior mutability or external
//! side effects.
//!
//! It is similar to the `Fn(&T, &U)` trait in the standard library.
//!
//! This module provides a unified `BiConsumer` trait and three
//! concrete implementations based on different ownership models:
//!
//! - **`BoxBiConsumer<T, U>`**: Box-based single ownership
//! - **`ArcBiConsumer<T, U>`**: Arc-based thread-safe shared ownership
//! - **`RcBiConsumer<T, U>`**: Rc-based single-threaded shared ownership
//!
//! # Design Philosophy
//!
//! BiConsumer uses `Fn(&T, &U)` semantics: it is invoked through `&self` and
//! receives shared references to both input values.
//!
//! Suitable for observation, logging, and notification scenarios with two
//! parameters. Compared to `StatefulBiConsumer`, `BiConsumer` does not require
//! wrapper-level interior mutability (`Mutex`/`RefCell`), making it more
//! efficient and easier to share.
// ==========================================================================
// Type Aliases
// ==========================================================================
/// Type alias for non-mutating bi-consumer function signature.
type BiConsumerFn<T, U> = dyn Fn;
/// Type alias for thread-safe non-mutating bi-consumer function signature.
type ThreadSafeBiConsumerFn<T, U> = dyn Fn + Send + Sync;
pub use BoxBiConsumer;
pub use RcBiConsumer;
pub use ArcBiConsumer;
pub use BoxConditionalBiConsumer;
pub use ArcConditionalBiConsumer;
pub use RcConditionalBiConsumer;
// =======================================================================
// 1. BiConsumer Trait - Unified Interface
// =======================================================================
/// BiConsumer trait - Unified non-mutating bi-consumer interface
///
/// It is similar to the `Fn(&T, &U)` trait in the standard library.
///
/// Defines core behavior for all non-mutating bi-consumer types. The API uses
/// `&self` and shared input references, so callers can use a bi-consumer
/// without granting mutable access to the consumer wrapper or input values.
///
/// # Automatic Implementations
///
/// - All closures implementing `Fn(&T, &U)`
/// - `BoxBiConsumer<T, U>`, `ArcBiConsumer<T, U>`, `RcBiConsumer<T, U>`
///
/// # Features
///
/// - **Unified Interface**: All non-mutating bi-consumer types share the same
/// `accept` method signature
/// - **Automatic Implementation**: Closures implement this trait directly,
/// without allocating an adapter
/// - **Generic Programming**: Write functions accepting any non-mutating
/// bi-consumer type
/// - **No Wrapper Interior Mutability**: No need for Mutex or RefCell in the
/// wrapper, making shared ownership more efficient
///
/// # Examples
///
/// ```rust
/// use qubit_function::{BiConsumer, BoxBiConsumer};
///
/// fn apply_consumer<C: BiConsumer<i32, i32>>(
/// consumer: &C,
/// a: &i32,
/// b: &i32
/// ) {
/// consumer.accept(a, b);
/// }
///
/// let box_con = BoxBiConsumer::new(|x: &i32, y: &i32| {
/// println!("Sum: {}", x + y);
/// });
/// apply_consumer(&box_con, &5, &3);
/// ```
crateimpl_closure_trait!;