pub trait ConsumerOnce<T> {
// Required method
fn accept(self, value: &T);
// Provided methods
fn into_box(self) -> BoxConsumerOnce<T>
where Self: Sized + 'static { ... }
fn into_fn(self) -> impl FnOnce(&T)
where Self: Sized + 'static { ... }
fn to_box(&self) -> BoxConsumerOnce<T>
where Self: Sized + Clone + 'static { ... }
fn to_fn(&self) -> impl FnOnce(&T)
where Self: Sized + Clone + 'static { ... }
}Expand description
ConsumerOnce trait - Unified one-time consumer interface
It is similar to the FnOnce(&T) trait in the standard library.
Defines the core behavior of all one-time consumer types. Similar to consumers
implementing FnOnce(&T), executes operations that accept a value reference but
return no result (only side effects), consuming itself in the process.
§Automatic Implementation
- All closures implementing
FnOnce(&T) BoxConsumerOnce<T>
§Features
- Unified Interface: All consumer types share the same
acceptmethod signature - Automatic Implementation: Closures automatically implement this trait with zero overhead
- Type Conversion: Can be converted to BoxConsumerOnce
- Generic Programming: Write functions that work with any one-time consumer type
§Examples
use qubit_function::{ConsumerOnce, BoxConsumerOnce};
use std::sync::{Arc, Mutex};
fn apply_consumer<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
consumer.accept(value);
}
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let box_con = BoxConsumerOnce::new(move |x: &i32| {
l.lock().expect("mutex should not be poisoned").push(*x);
});
apply_consumer(box_con, &5);
assert_eq!(*log.lock().expect("mutex should not be poisoned"), vec![5]);Required Methods§
Sourcefn accept(self, value: &T)
fn accept(self, value: &T)
Execute one-time consumption operation
Executes an operation on the given reference. The operation typically reads the input value or produces side effects, but does not modify the input value itself. Consumes self.
§Parameters
value- Reference to the value to be consumed
§Examples
use qubit_function::{ConsumerOnce, BoxConsumerOnce};
let consumer = BoxConsumerOnce::new(|x: &i32| println!("{}", x));
consumer.accept(&5);Provided Methods§
Sourcefn into_box(self) -> BoxConsumerOnce<T>where
Self: Sized + 'static,
fn into_box(self) -> BoxConsumerOnce<T>where
Self: Sized + 'static,
Convert to BoxConsumerOnce
⚠️ Consumes self: The original consumer will be unavailable after calling this method.
§Default Implementation
The default implementation wraps self in a BoxConsumerOnce by calling
accept on the consumer. Types can override this method to provide more
efficient conversions.
§Returns
Returns the wrapped BoxConsumerOnce<T>
§Examples
use qubit_function::ConsumerOnce;
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32| {
l.lock().expect("mutex should not be poisoned").push(*x);
};
let box_consumer = closure.into_box();
box_consumer.accept(&5);
assert_eq!(*log.lock().expect("mutex should not be poisoned"), vec![5]);Examples found in repository?
24fn main() {
25 println!("=== ConsumerOnce Demo ===\n");
26
27 // 1. BoxConsumerOnce - Single ownership, one-time use
28 println!("1. BoxConsumerOnce - Single ownership");
29 {
30 let log = Arc::new(Mutex::new(Vec::new()));
31 let l = log.clone();
32 let consumer = BoxConsumerOnce::new(move |x: &i32| {
33 l.lock().expect("mutex should not be poisoned").push(*x);
34 println!(" BoxConsumerOnce consumed: {}", x);
35 });
36 consumer.accept(&42);
37 println!(
38 " Log: {:?}\n",
39 *log.lock().expect("mutex should not be poisoned")
40 );
41 }
42
43 // 2. BoxConsumerOnce - Method chaining
44 println!("2. BoxConsumerOnce - Method chaining");
45 {
46 let log = Arc::new(Mutex::new(Vec::new()));
47 let l1 = log.clone();
48 let l2 = log.clone();
49 let l3 = log.clone();
50 let chained = BoxConsumerOnce::new(move |x: &i32| {
51 l1.lock()
52 .expect("mutex should not be poisoned")
53 .push(*x * 2);
54 println!(" Step 1: {} * 2 = {}", x, x * 2);
55 })
56 .and_then(move |x: &i32| {
57 l2.lock()
58 .expect("mutex should not be poisoned")
59 .push(*x + 10);
60 println!(" Step 2: {} + 10 = {}", x, x + 10);
61 })
62 .and_then(move |x: &i32| {
63 l3.lock()
64 .expect("mutex should not be poisoned")
65 .push(*x - 1);
66 println!(" Step 3: {} - 1 = {}", x, x - 1);
67 });
68 chained.accept(&5);
69 println!(
70 " Log: {:?}\n",
71 *log.lock().expect("mutex should not be poisoned")
72 );
73 }
74
75 // 3. BoxConsumerOnce - Factory methods
76 println!("3. BoxConsumerOnce - Factory methods");
77 {
78 // No-op consumer
79 let noop = BoxConsumerOnce::<i32>::noop();
80 noop.accept(&42);
81 println!(" No-op consumer executed (no output)");
82
83 // Print consumer
84 print!(" Print consumer: ");
85 let print = BoxConsumerOnce::new(|x: &i32| println!("{}", x));
86 print.accept(&42);
87
88 // Print with prefix
89 print!(" Print with prefix: ");
90 let print_with = BoxConsumerOnce::new(|x: &i32| println!("Value: {}", x));
91 print_with.accept(&42);
92
93 // Conditional consumer
94 let log = Arc::new(Mutex::new(Vec::new()));
95 let l = log.clone();
96 let conditional = BoxConsumerOnce::new(move |x: &i32| {
97 l.lock().expect("mutex should not be poisoned").push(*x * 2);
98 })
99 .when(|x: &i32| *x > 0);
100 conditional.accept(&5);
101 println!(
102 " Conditional (positive): {:?}",
103 *log.lock().expect("mutex should not be poisoned")
104 );
105
106 let log = Arc::new(Mutex::new(Vec::new()));
107 let l = log.clone();
108 let conditional = BoxConsumerOnce::new(move |x: &i32| {
109 l.lock().expect("mutex should not be poisoned").push(*x * 2);
110 })
111 .when(|x: &i32| *x > 0);
112 conditional.accept(&-5);
113 println!(
114 " Conditional (negative): {:?}\n",
115 *log.lock().expect("mutex should not be poisoned")
116 );
117 }
118
119 // 4. Closure usage
120 println!("4. Closure usage");
121 {
122 let log = Arc::new(Mutex::new(Vec::new()));
123 let l = log.clone();
124 let closure = move |x: &i32| {
125 l.lock().expect("mutex should not be poisoned").push(*x * 2);
126 println!(" Closure consumed: {}", x);
127 };
128 closure.accept(&42);
129 println!(
130 " Log: {:?}\n",
131 *log.lock().expect("mutex should not be poisoned")
132 );
133 }
134
135 // 5. Closure chaining
136 println!("5. Closure chaining");
137 {
138 let log = Arc::new(Mutex::new(Vec::new()));
139 let l1 = log.clone();
140 let l2 = log.clone();
141 let chained = (move |x: &i32| {
142 l1.lock()
143 .expect("mutex should not be poisoned")
144 .push(*x * 2);
145 println!(" Closure 1: {} * 2 = {}", x, x * 2);
146 })
147 .and_then(move |x: &i32| {
148 l2.lock()
149 .expect("mutex should not be poisoned")
150 .push(*x + 10);
151 println!(" Closure 2: {} + 10 = {}", x, x + 10);
152 });
153 chained.accept(&5);
154 println!(
155 " Log: {:?}\n",
156 *log.lock().expect("mutex should not be poisoned")
157 );
158 }
159
160 // 6. Type conversions
161 println!("6. Type conversions");
162 {
163 let log = Arc::new(Mutex::new(Vec::new()));
164
165 // Closure to BoxConsumerOnce
166 let l = log.clone();
167 let closure = move |x: &i32| {
168 l.lock().expect("mutex should not be poisoned").push(*x);
169 };
170 let box_consumer = closure.into_box();
171 box_consumer.accept(&1);
172 println!(
173 " BoxConsumerOnce: {:?}",
174 *log.lock().expect("mutex should not be poisoned")
175 );
176 }
177
178 // 7. Using with iterators (BoxConsumerOnce)
179 println!("7. Using with iterators");
180 {
181 let log = Arc::new(Mutex::new(Vec::new()));
182 let l = log.clone();
183 let consumer = BoxConsumerOnce::new(move |x: &i32| {
184 l.lock().expect("mutex should not be poisoned").push(*x * 2);
185 });
186 // Note: This will panic because BoxConsumerOnce can only be called once
187 // vec![1, 2, 3, 4, 5].iter().for_each(consumer.into_fn());
188 consumer.accept(&1);
189 println!(
190 " BoxConsumerOnce with single value: {:?}\n",
191 *log.lock().expect("mutex should not be poisoned")
192 );
193 }
194
195 println!("=== Demo Complete ===");
196}Sourcefn into_fn(self) -> impl FnOnce(&T)where
Self: Sized + 'static,
fn into_fn(self) -> impl FnOnce(&T)where
Self: Sized + 'static,
Convert to closure
⚠️ Consumes self: The original consumer will be unavailable after calling this method.
Converts a one-time consumer to a closure that can be used directly in places
where the standard library requires FnOnce.
§Default Implementation
The default implementation creates a closure that captures self and calls
its accept method. Types can override this method to provide more efficient
conversions.
§Returns
Returns a closure implementing FnOnce(&T)
§Examples
use qubit_function::ConsumerOnce;
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32| {
l.lock().expect("mutex should not be poisoned").push(*x * 2);
};
let func = closure.into_fn();
func(&5);
assert_eq!(*log.lock().expect("mutex should not be poisoned"), vec![10]);Sourcefn to_box(&self) -> BoxConsumerOnce<T>
fn to_box(&self) -> BoxConsumerOnce<T>
Convert to BoxConsumerOnce without consuming self
⚠️ Requires Clone: This method requires Self to implement
Clone. Clones the current consumer and wraps it in a
BoxConsumerOnce.
§Default Implementation
The default implementation clones self and then calls
into_box() on the clone. Types can override this method to
provide more efficient conversions.
§Returns
Returns the wrapped BoxConsumerOnce<T>
§Examples
use qubit_function::ConsumerOnce;
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32| {
l.lock().expect("mutex should not be poisoned").push(*x);
};
let box_consumer = closure.to_box();
box_consumer.accept(&5);
assert_eq!(*log.lock().expect("mutex should not be poisoned"), vec![5]);Sourcefn to_fn(&self) -> impl FnOnce(&T)
fn to_fn(&self) -> impl FnOnce(&T)
Convert to closure without consuming self
⚠️ Requires Clone: This method requires Self to implement
Clone. Clones the current consumer and then converts the clone
to a closure.
§Default Implementation
The default implementation clones self and then calls
into_fn() on the clone. Types can override this method to
provide more efficient conversions.
§Returns
Returns a closure implementing FnOnce(&T)
§Examples
use qubit_function::ConsumerOnce;
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32| {
l.lock().expect("mutex should not be poisoned").push(*x * 2);
};
let func = closure.to_fn();
func(&5);
assert_eq!(*log.lock().expect("mutex should not be poisoned"), vec![10]);