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
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! # BiConsumerOnce Types
//!
//! Provides one-time bi-consumer interface implementations for operations
//! accepting two input parameters without returning a result.
//!
//! It is similar to the `FnOnce(&T, &U)` trait in the standard library.
//!
//! This module provides a unified `BiConsumerOnce` trait and one concrete
//! implementation:
//!
//! - **`BoxBiConsumerOnce<T, U>`**: Box-based single ownership implementation
//!
//! # Why No Arc/Rc Variants?
//!
//! Unlike reusable [`BiConsumer`](crate::consumers::BiConsumer)
//! implementations, this module does **not** provide `ArcBiConsumerOnce` or
//! `RcBiConsumerOnce` implementations. This is a design decision based on the
//! fact that `FnOnce` semantics require single ownership at the call site,
//! while `Arc` and `Rc` are meant to preserve shared ownership across clones.
//!
//! # Design Philosophy
//!
//! BiConsumerOnce uses `FnOnce(&T, &U)` semantics: for truly one-time
//! consumption operations.
//!
//! Unlike BiConsumer, BiConsumerOnce consumes itself on first call. Suitable
//! for initialization callbacks, cleanup callbacks, etc.
// ==========================================================================
// Type Aliases
// ==========================================================================
/// Type alias for bi-consumer once function signature.
type BiConsumerOnceFn<T, U> = dyn FnOnce;
pub use BoxBiConsumerOnce;
pub use BoxConditionalBiConsumerOnce;
// =======================================================================
// 1. BiConsumerOnce Trait - Unified Interface
// =======================================================================
/// BiConsumerOnce trait - Unified one-time bi-consumer interface
///
/// It is similar to the `FnOnce(&T, &U)` trait in the standard library.
///
/// Defines core behavior for all one-time bi-consumer types. Similar to a
/// bi-consumer implementing `FnOnce(&T, &U)`, performs operations
/// accepting two value references but returning no result (side effects
/// only), consuming itself in the process.
///
/// # Automatic Implementations
///
/// - All closures implementing `FnOnce(&T, &U)`
/// - `BoxBiConsumerOnce<T, U>`
///
/// # Features
///
/// - **Unified Interface**: All 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 one-time
/// bi-consumer type
///
/// # Examples
///
/// ```rust
/// use qubit_function::{BiConsumerOnce, BoxBiConsumerOnce};
/// use std::sync::{Arc, Mutex};
///
/// fn apply_consumer<C: BiConsumerOnce<i32, i32>>(
/// consumer: C,
/// a: &i32,
/// b: &i32
/// ) {
/// consumer.accept(a, b);
/// }
///
/// let log = Arc::new(Mutex::new(Vec::new()));
/// let l = log.clone();
/// let box_con = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
/// l.lock().expect("mutex should not be poisoned").push(*x + *y);
/// });
/// apply_consumer(box_con, &5, &3);
/// assert_eq!(*log.lock().expect("mutex should not be poisoned"), vec![8]);
/// ```