pub trait Consumer<T> {
// Required method
fn accept(&self, value: &T);
// Provided methods
fn into_box(self) -> BoxConsumer<T>
where Self: Sized + 'static { ... }
fn into_rc(self) -> RcConsumer<T>
where Self: Sized + 'static { ... }
fn into_arc(self) -> ArcConsumer<T>
where Self: Sized + Send + Sync + 'static { ... }
fn into_fn(self) -> impl Fn(&T)
where Self: Sized + 'static { ... }
fn into_once(self) -> BoxConsumerOnce<T>
where Self: Sized + 'static { ... }
fn to_box(&self) -> BoxConsumer<T>
where Self: Clone + 'static { ... }
fn to_rc(&self) -> RcConsumer<T>
where Self: Clone + 'static { ... }
fn to_arc(&self) -> ArcConsumer<T>
where Self: Clone + Send + Sync + 'static { ... }
fn to_fn(&self) -> impl Fn(&T)
where Self: Clone + 'static { ... }
fn to_once(&self) -> BoxConsumerOnce<T>
where Self: Clone + 'static { ... }
}Expand description
Consumer trait - Unified non-mutating consumer interface
It is similar to the Fn(&T) trait in the standard library.
Defines the core behavior of all non-mutating consumer types. The API uses
&self and shared input references, so callers can use a consumer without
granting mutable access to the consumer wrapper or input value.
§Auto-implementation
- All closures implementing
Fn(&T) BoxConsumer<T>,ArcConsumer<T>,RcConsumer<T>
§Features
- Unified Interface: All non-mutating consumer types share the same
acceptmethod signature - Auto-implementation: Closures automatically implement this trait with zero overhead
- Type Conversion: Easy conversion between different ownership models
- Generic Programming: Write functions that work with any non-mutating consumer type
- No Wrapper Interior Mutability: No need for Mutex or RefCell in the wrapper, making shared ownership more efficient
§Examples
use qubit_function::{Consumer, BoxConsumer};
fn apply_consumer<C: Consumer<i32>>(consumer: &C, value: &i32) {
consumer.accept(value);
}
let box_con = BoxConsumer::new(|x: &i32| {
println!("Value: {}", x);
});
apply_consumer(&box_con, &5);Required Methods§
Sourcefn accept(&self, value: &T)
fn accept(&self, value: &T)
Execute non-mutating consumption operation
Performs an operation on the given reference. The operation typically reads input values or produces side effects, but neither modifies the input value nor the consumer’s own state.
§Parameters
value- Reference to the value to consume
§Examples
use qubit_function::{Consumer, BoxConsumer};
let consumer = BoxConsumer::new(|x: &i32| println!("{}", x));
consumer.accept(&5);Provided Methods§
Sourcefn into_box(self) -> BoxConsumer<T>where
Self: Sized + 'static,
fn into_box(self) -> BoxConsumer<T>where
Self: Sized + 'static,
Convert to BoxConsumer
⚠️ Consumes self: The original consumer will be unavailable after
calling this method.
§Returns
Returns the wrapped BoxConsumer<T>
Examples found in repository?
34fn main() {
35 println!("=== Consumer Examples ===\n");
36 println!("Note: Consumer only reads values, does not modify the original value");
37 println!("If you need to modify values, please refer to mutator_demo.rs\n");
38
39 // ========================================================================
40 // Example 1: BoxConsumer basic usage
41 // ========================================================================
42 println!("Example 1: BoxConsumer basic usage");
43 println!("{}", "-".repeat(50));
44
45 let consumer = BoxConsumer::new(|x: &i32| {
46 println!("Read and calculate: {} * 2 = {}", x, x * 2);
47 });
48 let value = 5;
49 println!("Value: {}", value);
50 consumer.accept(&value);
51 println!("Value remains: {} (not modified)\n", value);
52
53 // ========================================================================
54 // Example 2: BoxConsumer method chaining
55 // ========================================================================
56 println!("Example 2: BoxConsumer method chaining");
57 println!("{}", "-".repeat(50));
58
59 let results = Arc::new(Mutex::new(Vec::new()));
60 let r1 = results.clone();
61 let r2 = results.clone();
62 let r3 = results.clone();
63
64 let chained = BoxConsumer::new(move |x: &i32| {
65 r1.lock()
66 .expect("mutex should not be poisoned")
67 .push(*x * 2);
68 })
69 .and_then(move |x: &i32| {
70 r2.lock()
71 .expect("mutex should not be poisoned")
72 .push(*x + 10);
73 })
74 .and_then(move |x: &i32| {
75 r3.lock().expect("mutex should not be poisoned").push(*x);
76 println!("Processing value: {}", x);
77 });
78
79 let value = 5;
80 println!("Initial value: {}", value);
81 chained.accept(&value);
82 println!(
83 "Collected results: {:?}",
84 *results.lock().expect("mutex should not be poisoned")
85 );
86 println!("Original value: {} (not modified)\n", value);
87
88 // ========================================================================
89 // Example 3: Closure extension methods
90 // ========================================================================
91 println!("Example 3: Direct use of extension methods on closures");
92 println!("{}", "-".repeat(50));
93
94 let result = Arc::new(Mutex::new(0));
95 let r1 = result.clone();
96 let r2 = result.clone();
97
98 let closure_chain = (move |x: &i32| {
99 *r1.lock().expect("mutex should not be poisoned") = *x * 2;
100 })
101 .and_then(move |_x: &i32| {
102 *r2.lock().expect("mutex should not be poisoned") += 10;
103 });
104
105 let value = 5;
106 println!("Initial value: {}", value);
107 closure_chain.accept(&value);
108 println!(
109 "Calculation result: {}",
110 *result.lock().expect("mutex should not be poisoned")
111 );
112 println!("Original value: {} (not modified)\n", value);
113
114 // ========================================================================
115 // Example 4: BoxConsumer factory methods
116 // ========================================================================
117 println!("Example 4: BoxConsumer factory methods");
118 println!("{}", "-".repeat(50));
119
120 // noop
121 println!("noop - does nothing:");
122 let noop = BoxConsumer::<i32>::noop();
123 let value = 42;
124 noop.accept(&value);
125 println!("Value: {}\n", value);
126
127 // print
128 print!("print - prints value: ");
129 let print = BoxConsumer::new(|x: &i32| println!("{}", x));
130 let value = 42;
131 print.accept(&value);
132 println!();
133
134 // print with prefix
135 let print_with = BoxConsumer::new(|x: &i32| println!("Value is: {}", x));
136 let value = 42;
137 print_with.accept(&value);
138 println!();
139
140 // ========================================================================
141 // Example 5: Conditional Consumer
142 // ========================================================================
143 println!("Example 5: Conditional Consumer");
144 println!("{}", "-".repeat(50));
145
146 // when
147 let mut check_positive =
148 BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x)).when(|x: &i32| *x > 0);
149
150 let positive = 5;
151 let negative = -5;
152 print!("Check {}: ", positive);
153 check_positive.accept(&positive);
154 print!("Check {}: ", negative);
155 check_positive.accept(&negative);
156 println!("(negative numbers not printed)\n");
157
158 // when().or_else()
159 let mut categorize = BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x))
160 .when(|x: &i32| *x > 0)
161 .or_else(|x: &i32| println!("Non-positive: {}", x));
162
163 let positive = 10;
164 let negative = -10;
165 categorize.accept(&positive);
166 categorize.accept(&negative);
167 println!();
168
169 // ========================================================================
170 // Example 6: ArcConsumer - multi-threaded sharing
171 // ========================================================================
172 println!("Example 6: ArcConsumer - multi-threaded sharing");
173 println!("{}", "-".repeat(50));
174
175 let shared = ArcConsumer::new(|x: &i32| println!("Processing value: {}", x * 2));
176
177 // Clone for another thread
178 let shared_clone = shared.clone();
179 let handle = thread::spawn(move || {
180 let value = 5;
181 let consumer = shared_clone;
182 consumer.accept(&value);
183 value
184 });
185
186 // Use in main thread
187 let value = 3;
188 let consumer = shared;
189 consumer.accept(&value);
190
191 let thread_result = handle.join().expect("thread should not panic");
192 println!("Thread result: {}\n", thread_result);
193
194 // ========================================================================
195 // Example 7: ArcConsumer composition (does not consume original consumer)
196 // ========================================================================
197 println!("Example 7: ArcConsumer composition (borrowing &self)");
198 println!("{}", "-".repeat(50));
199
200 let double = ArcConsumer::new(|x: &i32| println!("double: {}", x * 2));
201 let add_ten = ArcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
202
203 // Composition does not consume original consumer
204 let pipeline1 = double.and_then(add_ten.clone());
205 let pipeline2 = add_ten.and_then(double.clone());
206
207 let value1 = 5;
208 let p1 = pipeline1;
209 print!("pipeline1 processing 5: ");
210 p1.accept(&value1);
211
212 let value2 = 5;
213 let p2 = pipeline2;
214 print!("pipeline2 processing 5: ");
215 p2.accept(&value2);
216
217 // double and add_ten are still available
218 let value3 = 10;
219 let d = double;
220 print!("Original double still available, processing 10: ");
221 d.accept(&value3);
222 println!();
223
224 // ========================================================================
225 // Example 8: RcConsumer - single-threaded sharing
226 // ========================================================================
227 println!("Example 8: RcConsumer - single-threaded sharing");
228 println!("{}", "-".repeat(50));
229
230 let rc_consumer = RcConsumer::new(|x: &i32| println!("Processing: {}", x * 2));
231
232 // Clone multiple copies
233 let clone1 = rc_consumer.clone();
234 let clone2 = rc_consumer.clone();
235
236 let value1 = 5;
237 let c1 = clone1;
238 print!("clone1 processing 5: ");
239 c1.accept(&value1);
240
241 let value2 = 3;
242 let c2 = clone2;
243 print!("clone2 processing 3: ");
244 c2.accept(&value2);
245
246 let value3 = 7;
247 let c3 = rc_consumer;
248 print!("Original processing 7: ");
249 c3.accept(&value3);
250 println!();
251
252 // ========================================================================
253 // Example 9: RcConsumer composition (borrowing &self)
254 // ========================================================================
255 println!("Example 9: RcConsumer composition (borrowing &self)");
256 println!("{}", "-".repeat(50));
257
258 let double = RcConsumer::new(|x: &i32| println!("double: {}", x * 2));
259 let add_ten = RcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
260
261 let pipeline1 = double.and_then(add_ten.clone());
262 let pipeline2 = add_ten.and_then(double.clone());
263
264 let value1 = 5;
265 let p1 = pipeline1;
266 print!("pipeline1 processing 5: ");
267 p1.accept(&value1);
268
269 let value2 = 5;
270 let p2 = pipeline2;
271 print!("pipeline2 processing 5: ");
272 p2.accept(&value2);
273 println!();
274
275 // ========================================================================
276 // Example 10: Unified Consumer trait
277 // ========================================================================
278 println!("Example 10: Unified Consumer trait");
279 println!("{}", "-".repeat(50));
280
281 fn log_all<C: Consumer<i32>>(consumer: &mut C, values: &[i32]) {
282 for value in values.iter() {
283 consumer.accept(value);
284 }
285 }
286
287 let values = vec![1, 2, 3, 4, 5];
288
289 let mut box_con = BoxConsumer::new(|x: &i32| print!("{} ", x * 2));
290 print!("BoxConsumer processing {:?}: ", values);
291 log_all(&mut box_con, &values);
292 println!();
293
294 let mut arc_con = ArcConsumer::new(|x: &i32| print!("{} ", x * 2));
295 print!("ArcConsumer processing {:?}: ", values);
296 log_all(&mut arc_con, &values);
297 println!();
298
299 let mut rc_con = RcConsumer::new(|x: &i32| print!("{} ", x * 2));
300 print!("RcConsumer processing {:?}: ", values);
301 log_all(&mut rc_con, &values);
302 println!();
303
304 let mut closure = |x: &i32| print!("{} ", x * 2);
305 print!("Closure processing {:?}: ", values);
306 log_all(&mut closure, &values);
307 println!("\n");
308
309 // ========================================================================
310 // Example 11: Data validation and logging
311 // ========================================================================
312 println!("Example 11: Data validation and logging");
313 println!("{}", "-".repeat(50));
314
315 let validator = BoxConsumer::new(|x: &i32| {
316 let status = if *x >= 0 && *x <= 100 {
317 "valid"
318 } else {
319 "out of range"
320 };
321 println!("Validate {}: {}", x, status);
322 });
323
324 let logger = BoxConsumer::new(|x: &i32| {
325 println!("Log to file: value={}, square={}", x, x * x);
326 });
327
328 let pipeline = validator.and_then(logger);
329
330 let test_values = vec![-50, 30, 200];
331 for value in test_values {
332 pipeline.accept(&value);
333 }
334 println!();
335
336 // ========================================================================
337 // Example 12: String analysis
338 // ========================================================================
339 println!("Example 12: String analysis");
340 println!("{}", "-".repeat(50));
341
342 let string_analyzer = BoxConsumer::new(|s: &String| {
343 println!("Length: {}", s.len());
344 })
345 .and_then(|s: &String| {
346 println!("Lowercase: {}", s.to_lowercase());
347 })
348 .and_then(|s: &String| {
349 println!("Uppercase: {}", s.to_uppercase());
350 })
351 .and_then(|s: &String| {
352 let word_count = s.split_whitespace().count();
353 println!("Word count: {}", word_count);
354 });
355
356 let text = String::from("Hello World");
357 println!("Analyzing text: \"{}\"", text);
358 string_analyzer.accept(&text);
359 println!("Original text: \"{}\" (not modified)\n", text);
360
361 // ========================================================================
362 // Example 13: Type conversion
363 // ========================================================================
364 println!("Example 13: Type conversion");
365 println!("{}", "-".repeat(50));
366
367 // Closure -> BoxConsumer
368 let closure = |x: &i32| print!("Processing: {} ", x * 2);
369 let box_con = Consumer::into_box(closure);
370 let value = 5;
371 print!("Closure -> BoxConsumer: ");
372 box_con.accept(&value);
373 println!();
374
375 // Closure -> RcConsumer
376 let closure = |x: &i32| print!("Processing: {} ", x * 2);
377 let rc_con = Consumer::into_rc(closure);
378 let value = 5;
379 print!("Closure -> RcConsumer: ");
380 rc_con.accept(&value);
381 println!();
382
383 // Closure -> ArcConsumer
384 let closure = |x: &i32| print!("Processing: {} ", x * 2);
385 let arc_con = Consumer::into_arc(closure);
386 let value = 5;
387 print!("Closure -> ArcConsumer: ");
388 arc_con.accept(&value);
389 println!();
390
391 // BoxConsumer -> RcConsumer
392 let box_con = BoxConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
393 let rc_con = box_con.into_rc();
394 let value = 5;
395 print!("BoxConsumer -> RcConsumer: ");
396 rc_con.accept(&value);
397 println!();
398
399 // RcConsumer -> BoxConsumer
400 let rc_con = RcConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
401 let box_con = rc_con.into_box();
402 let value = 5;
403 print!("RcConsumer -> BoxConsumer: ");
404 box_con.accept(&value);
405 println!("\n");
406
407 // ========================================================================
408 // Example 14: Custom types
409 // ========================================================================
410 println!("Example 14: Custom types");
411 println!("{}", "-".repeat(50));
412
413 #[derive(Debug, Clone)]
414 struct Point {
415 x: i32,
416 y: i32,
417 }
418
419 let analyzer = BoxConsumer::new(|p: &Point| {
420 println!("Point coordinates: ({}, {})", p.x, p.y);
421 })
422 .and_then(|p: &Point| {
423 let distance = ((p.x * p.x + p.y * p.y) as f64).sqrt();
424 println!("Distance from origin: {:.2}", distance);
425 })
426 .and_then(|p: &Point| {
427 let quadrant = match (p.x >= 0, p.y >= 0) {
428 (true, true) => "First quadrant",
429 (false, true) => "Second quadrant",
430 (false, false) => "Third quadrant",
431 (true, false) => "Fourth quadrant",
432 };
433 println!("Quadrant: {}", quadrant);
434 });
435
436 let point = Point { x: 3, y: 4 };
437 println!("Analyzing point: {:?}", point);
438 analyzer.accept(&point);
439 println!("Original point: {:?} (not modified)\n", point);
440
441 // ========================================================================
442 // Example 15: Data collection and statistics
443 // ========================================================================
444 println!("Example 15: Data collection and statistics");
445 println!("{}", "-".repeat(50));
446
447 let sum = Arc::new(Mutex::new(0));
448 let count = Arc::new(Mutex::new(0));
449 let sum_clone = sum.clone();
450 let count_clone = count.clone();
451
452 let collector = BoxConsumer::new(move |x: &i32| {
453 *sum_clone.lock().expect("mutex should not be poisoned") += *x;
454 *count_clone.lock().expect("mutex should not be poisoned") += 1;
455 });
456
457 let numbers = vec![10, 20, 30, 40, 50];
458 println!("Numbers: {:?}", numbers);
459 for num in &numbers {
460 collector.accept(num);
461 }
462
463 let total = *sum.lock().expect("mutex should not be poisoned");
464 let cnt = *count.lock().expect("mutex should not be poisoned");
465 println!("Sum: {}", total);
466 println!("Count: {}", cnt);
467 println!("Average: {:.2}\n", total as f64 / cnt as f64);
468
469 println!("=== All examples completed ===");
470 println!("\nTip: For value modification functionality, please refer to mutator_demo.rs");
471}Sourcefn into_rc(self) -> RcConsumer<T>where
Self: Sized + 'static,
fn into_rc(self) -> RcConsumer<T>where
Self: Sized + 'static,
Convert to RcConsumer
⚠️ Consumes self: The original consumer will be unavailable after
calling this method.
§Returns
Returns the wrapped RcConsumer<T>
Examples found in repository?
34fn main() {
35 println!("=== Consumer Examples ===\n");
36 println!("Note: Consumer only reads values, does not modify the original value");
37 println!("If you need to modify values, please refer to mutator_demo.rs\n");
38
39 // ========================================================================
40 // Example 1: BoxConsumer basic usage
41 // ========================================================================
42 println!("Example 1: BoxConsumer basic usage");
43 println!("{}", "-".repeat(50));
44
45 let consumer = BoxConsumer::new(|x: &i32| {
46 println!("Read and calculate: {} * 2 = {}", x, x * 2);
47 });
48 let value = 5;
49 println!("Value: {}", value);
50 consumer.accept(&value);
51 println!("Value remains: {} (not modified)\n", value);
52
53 // ========================================================================
54 // Example 2: BoxConsumer method chaining
55 // ========================================================================
56 println!("Example 2: BoxConsumer method chaining");
57 println!("{}", "-".repeat(50));
58
59 let results = Arc::new(Mutex::new(Vec::new()));
60 let r1 = results.clone();
61 let r2 = results.clone();
62 let r3 = results.clone();
63
64 let chained = BoxConsumer::new(move |x: &i32| {
65 r1.lock()
66 .expect("mutex should not be poisoned")
67 .push(*x * 2);
68 })
69 .and_then(move |x: &i32| {
70 r2.lock()
71 .expect("mutex should not be poisoned")
72 .push(*x + 10);
73 })
74 .and_then(move |x: &i32| {
75 r3.lock().expect("mutex should not be poisoned").push(*x);
76 println!("Processing value: {}", x);
77 });
78
79 let value = 5;
80 println!("Initial value: {}", value);
81 chained.accept(&value);
82 println!(
83 "Collected results: {:?}",
84 *results.lock().expect("mutex should not be poisoned")
85 );
86 println!("Original value: {} (not modified)\n", value);
87
88 // ========================================================================
89 // Example 3: Closure extension methods
90 // ========================================================================
91 println!("Example 3: Direct use of extension methods on closures");
92 println!("{}", "-".repeat(50));
93
94 let result = Arc::new(Mutex::new(0));
95 let r1 = result.clone();
96 let r2 = result.clone();
97
98 let closure_chain = (move |x: &i32| {
99 *r1.lock().expect("mutex should not be poisoned") = *x * 2;
100 })
101 .and_then(move |_x: &i32| {
102 *r2.lock().expect("mutex should not be poisoned") += 10;
103 });
104
105 let value = 5;
106 println!("Initial value: {}", value);
107 closure_chain.accept(&value);
108 println!(
109 "Calculation result: {}",
110 *result.lock().expect("mutex should not be poisoned")
111 );
112 println!("Original value: {} (not modified)\n", value);
113
114 // ========================================================================
115 // Example 4: BoxConsumer factory methods
116 // ========================================================================
117 println!("Example 4: BoxConsumer factory methods");
118 println!("{}", "-".repeat(50));
119
120 // noop
121 println!("noop - does nothing:");
122 let noop = BoxConsumer::<i32>::noop();
123 let value = 42;
124 noop.accept(&value);
125 println!("Value: {}\n", value);
126
127 // print
128 print!("print - prints value: ");
129 let print = BoxConsumer::new(|x: &i32| println!("{}", x));
130 let value = 42;
131 print.accept(&value);
132 println!();
133
134 // print with prefix
135 let print_with = BoxConsumer::new(|x: &i32| println!("Value is: {}", x));
136 let value = 42;
137 print_with.accept(&value);
138 println!();
139
140 // ========================================================================
141 // Example 5: Conditional Consumer
142 // ========================================================================
143 println!("Example 5: Conditional Consumer");
144 println!("{}", "-".repeat(50));
145
146 // when
147 let mut check_positive =
148 BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x)).when(|x: &i32| *x > 0);
149
150 let positive = 5;
151 let negative = -5;
152 print!("Check {}: ", positive);
153 check_positive.accept(&positive);
154 print!("Check {}: ", negative);
155 check_positive.accept(&negative);
156 println!("(negative numbers not printed)\n");
157
158 // when().or_else()
159 let mut categorize = BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x))
160 .when(|x: &i32| *x > 0)
161 .or_else(|x: &i32| println!("Non-positive: {}", x));
162
163 let positive = 10;
164 let negative = -10;
165 categorize.accept(&positive);
166 categorize.accept(&negative);
167 println!();
168
169 // ========================================================================
170 // Example 6: ArcConsumer - multi-threaded sharing
171 // ========================================================================
172 println!("Example 6: ArcConsumer - multi-threaded sharing");
173 println!("{}", "-".repeat(50));
174
175 let shared = ArcConsumer::new(|x: &i32| println!("Processing value: {}", x * 2));
176
177 // Clone for another thread
178 let shared_clone = shared.clone();
179 let handle = thread::spawn(move || {
180 let value = 5;
181 let consumer = shared_clone;
182 consumer.accept(&value);
183 value
184 });
185
186 // Use in main thread
187 let value = 3;
188 let consumer = shared;
189 consumer.accept(&value);
190
191 let thread_result = handle.join().expect("thread should not panic");
192 println!("Thread result: {}\n", thread_result);
193
194 // ========================================================================
195 // Example 7: ArcConsumer composition (does not consume original consumer)
196 // ========================================================================
197 println!("Example 7: ArcConsumer composition (borrowing &self)");
198 println!("{}", "-".repeat(50));
199
200 let double = ArcConsumer::new(|x: &i32| println!("double: {}", x * 2));
201 let add_ten = ArcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
202
203 // Composition does not consume original consumer
204 let pipeline1 = double.and_then(add_ten.clone());
205 let pipeline2 = add_ten.and_then(double.clone());
206
207 let value1 = 5;
208 let p1 = pipeline1;
209 print!("pipeline1 processing 5: ");
210 p1.accept(&value1);
211
212 let value2 = 5;
213 let p2 = pipeline2;
214 print!("pipeline2 processing 5: ");
215 p2.accept(&value2);
216
217 // double and add_ten are still available
218 let value3 = 10;
219 let d = double;
220 print!("Original double still available, processing 10: ");
221 d.accept(&value3);
222 println!();
223
224 // ========================================================================
225 // Example 8: RcConsumer - single-threaded sharing
226 // ========================================================================
227 println!("Example 8: RcConsumer - single-threaded sharing");
228 println!("{}", "-".repeat(50));
229
230 let rc_consumer = RcConsumer::new(|x: &i32| println!("Processing: {}", x * 2));
231
232 // Clone multiple copies
233 let clone1 = rc_consumer.clone();
234 let clone2 = rc_consumer.clone();
235
236 let value1 = 5;
237 let c1 = clone1;
238 print!("clone1 processing 5: ");
239 c1.accept(&value1);
240
241 let value2 = 3;
242 let c2 = clone2;
243 print!("clone2 processing 3: ");
244 c2.accept(&value2);
245
246 let value3 = 7;
247 let c3 = rc_consumer;
248 print!("Original processing 7: ");
249 c3.accept(&value3);
250 println!();
251
252 // ========================================================================
253 // Example 9: RcConsumer composition (borrowing &self)
254 // ========================================================================
255 println!("Example 9: RcConsumer composition (borrowing &self)");
256 println!("{}", "-".repeat(50));
257
258 let double = RcConsumer::new(|x: &i32| println!("double: {}", x * 2));
259 let add_ten = RcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
260
261 let pipeline1 = double.and_then(add_ten.clone());
262 let pipeline2 = add_ten.and_then(double.clone());
263
264 let value1 = 5;
265 let p1 = pipeline1;
266 print!("pipeline1 processing 5: ");
267 p1.accept(&value1);
268
269 let value2 = 5;
270 let p2 = pipeline2;
271 print!("pipeline2 processing 5: ");
272 p2.accept(&value2);
273 println!();
274
275 // ========================================================================
276 // Example 10: Unified Consumer trait
277 // ========================================================================
278 println!("Example 10: Unified Consumer trait");
279 println!("{}", "-".repeat(50));
280
281 fn log_all<C: Consumer<i32>>(consumer: &mut C, values: &[i32]) {
282 for value in values.iter() {
283 consumer.accept(value);
284 }
285 }
286
287 let values = vec![1, 2, 3, 4, 5];
288
289 let mut box_con = BoxConsumer::new(|x: &i32| print!("{} ", x * 2));
290 print!("BoxConsumer processing {:?}: ", values);
291 log_all(&mut box_con, &values);
292 println!();
293
294 let mut arc_con = ArcConsumer::new(|x: &i32| print!("{} ", x * 2));
295 print!("ArcConsumer processing {:?}: ", values);
296 log_all(&mut arc_con, &values);
297 println!();
298
299 let mut rc_con = RcConsumer::new(|x: &i32| print!("{} ", x * 2));
300 print!("RcConsumer processing {:?}: ", values);
301 log_all(&mut rc_con, &values);
302 println!();
303
304 let mut closure = |x: &i32| print!("{} ", x * 2);
305 print!("Closure processing {:?}: ", values);
306 log_all(&mut closure, &values);
307 println!("\n");
308
309 // ========================================================================
310 // Example 11: Data validation and logging
311 // ========================================================================
312 println!("Example 11: Data validation and logging");
313 println!("{}", "-".repeat(50));
314
315 let validator = BoxConsumer::new(|x: &i32| {
316 let status = if *x >= 0 && *x <= 100 {
317 "valid"
318 } else {
319 "out of range"
320 };
321 println!("Validate {}: {}", x, status);
322 });
323
324 let logger = BoxConsumer::new(|x: &i32| {
325 println!("Log to file: value={}, square={}", x, x * x);
326 });
327
328 let pipeline = validator.and_then(logger);
329
330 let test_values = vec![-50, 30, 200];
331 for value in test_values {
332 pipeline.accept(&value);
333 }
334 println!();
335
336 // ========================================================================
337 // Example 12: String analysis
338 // ========================================================================
339 println!("Example 12: String analysis");
340 println!("{}", "-".repeat(50));
341
342 let string_analyzer = BoxConsumer::new(|s: &String| {
343 println!("Length: {}", s.len());
344 })
345 .and_then(|s: &String| {
346 println!("Lowercase: {}", s.to_lowercase());
347 })
348 .and_then(|s: &String| {
349 println!("Uppercase: {}", s.to_uppercase());
350 })
351 .and_then(|s: &String| {
352 let word_count = s.split_whitespace().count();
353 println!("Word count: {}", word_count);
354 });
355
356 let text = String::from("Hello World");
357 println!("Analyzing text: \"{}\"", text);
358 string_analyzer.accept(&text);
359 println!("Original text: \"{}\" (not modified)\n", text);
360
361 // ========================================================================
362 // Example 13: Type conversion
363 // ========================================================================
364 println!("Example 13: Type conversion");
365 println!("{}", "-".repeat(50));
366
367 // Closure -> BoxConsumer
368 let closure = |x: &i32| print!("Processing: {} ", x * 2);
369 let box_con = Consumer::into_box(closure);
370 let value = 5;
371 print!("Closure -> BoxConsumer: ");
372 box_con.accept(&value);
373 println!();
374
375 // Closure -> RcConsumer
376 let closure = |x: &i32| print!("Processing: {} ", x * 2);
377 let rc_con = Consumer::into_rc(closure);
378 let value = 5;
379 print!("Closure -> RcConsumer: ");
380 rc_con.accept(&value);
381 println!();
382
383 // Closure -> ArcConsumer
384 let closure = |x: &i32| print!("Processing: {} ", x * 2);
385 let arc_con = Consumer::into_arc(closure);
386 let value = 5;
387 print!("Closure -> ArcConsumer: ");
388 arc_con.accept(&value);
389 println!();
390
391 // BoxConsumer -> RcConsumer
392 let box_con = BoxConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
393 let rc_con = box_con.into_rc();
394 let value = 5;
395 print!("BoxConsumer -> RcConsumer: ");
396 rc_con.accept(&value);
397 println!();
398
399 // RcConsumer -> BoxConsumer
400 let rc_con = RcConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
401 let box_con = rc_con.into_box();
402 let value = 5;
403 print!("RcConsumer -> BoxConsumer: ");
404 box_con.accept(&value);
405 println!("\n");
406
407 // ========================================================================
408 // Example 14: Custom types
409 // ========================================================================
410 println!("Example 14: Custom types");
411 println!("{}", "-".repeat(50));
412
413 #[derive(Debug, Clone)]
414 struct Point {
415 x: i32,
416 y: i32,
417 }
418
419 let analyzer = BoxConsumer::new(|p: &Point| {
420 println!("Point coordinates: ({}, {})", p.x, p.y);
421 })
422 .and_then(|p: &Point| {
423 let distance = ((p.x * p.x + p.y * p.y) as f64).sqrt();
424 println!("Distance from origin: {:.2}", distance);
425 })
426 .and_then(|p: &Point| {
427 let quadrant = match (p.x >= 0, p.y >= 0) {
428 (true, true) => "First quadrant",
429 (false, true) => "Second quadrant",
430 (false, false) => "Third quadrant",
431 (true, false) => "Fourth quadrant",
432 };
433 println!("Quadrant: {}", quadrant);
434 });
435
436 let point = Point { x: 3, y: 4 };
437 println!("Analyzing point: {:?}", point);
438 analyzer.accept(&point);
439 println!("Original point: {:?} (not modified)\n", point);
440
441 // ========================================================================
442 // Example 15: Data collection and statistics
443 // ========================================================================
444 println!("Example 15: Data collection and statistics");
445 println!("{}", "-".repeat(50));
446
447 let sum = Arc::new(Mutex::new(0));
448 let count = Arc::new(Mutex::new(0));
449 let sum_clone = sum.clone();
450 let count_clone = count.clone();
451
452 let collector = BoxConsumer::new(move |x: &i32| {
453 *sum_clone.lock().expect("mutex should not be poisoned") += *x;
454 *count_clone.lock().expect("mutex should not be poisoned") += 1;
455 });
456
457 let numbers = vec![10, 20, 30, 40, 50];
458 println!("Numbers: {:?}", numbers);
459 for num in &numbers {
460 collector.accept(num);
461 }
462
463 let total = *sum.lock().expect("mutex should not be poisoned");
464 let cnt = *count.lock().expect("mutex should not be poisoned");
465 println!("Sum: {}", total);
466 println!("Count: {}", cnt);
467 println!("Average: {:.2}\n", total as f64 / cnt as f64);
468
469 println!("=== All examples completed ===");
470 println!("\nTip: For value modification functionality, please refer to mutator_demo.rs");
471}Sourcefn into_arc(self) -> ArcConsumer<T>
fn into_arc(self) -> ArcConsumer<T>
Convert to ArcConsumer
⚠️ Consumes self: The original consumer will be unavailable after
calling this method.
§Returns
Returns the wrapped ArcConsumer<T>
Examples found in repository?
34fn main() {
35 println!("=== Consumer Examples ===\n");
36 println!("Note: Consumer only reads values, does not modify the original value");
37 println!("If you need to modify values, please refer to mutator_demo.rs\n");
38
39 // ========================================================================
40 // Example 1: BoxConsumer basic usage
41 // ========================================================================
42 println!("Example 1: BoxConsumer basic usage");
43 println!("{}", "-".repeat(50));
44
45 let consumer = BoxConsumer::new(|x: &i32| {
46 println!("Read and calculate: {} * 2 = {}", x, x * 2);
47 });
48 let value = 5;
49 println!("Value: {}", value);
50 consumer.accept(&value);
51 println!("Value remains: {} (not modified)\n", value);
52
53 // ========================================================================
54 // Example 2: BoxConsumer method chaining
55 // ========================================================================
56 println!("Example 2: BoxConsumer method chaining");
57 println!("{}", "-".repeat(50));
58
59 let results = Arc::new(Mutex::new(Vec::new()));
60 let r1 = results.clone();
61 let r2 = results.clone();
62 let r3 = results.clone();
63
64 let chained = BoxConsumer::new(move |x: &i32| {
65 r1.lock()
66 .expect("mutex should not be poisoned")
67 .push(*x * 2);
68 })
69 .and_then(move |x: &i32| {
70 r2.lock()
71 .expect("mutex should not be poisoned")
72 .push(*x + 10);
73 })
74 .and_then(move |x: &i32| {
75 r3.lock().expect("mutex should not be poisoned").push(*x);
76 println!("Processing value: {}", x);
77 });
78
79 let value = 5;
80 println!("Initial value: {}", value);
81 chained.accept(&value);
82 println!(
83 "Collected results: {:?}",
84 *results.lock().expect("mutex should not be poisoned")
85 );
86 println!("Original value: {} (not modified)\n", value);
87
88 // ========================================================================
89 // Example 3: Closure extension methods
90 // ========================================================================
91 println!("Example 3: Direct use of extension methods on closures");
92 println!("{}", "-".repeat(50));
93
94 let result = Arc::new(Mutex::new(0));
95 let r1 = result.clone();
96 let r2 = result.clone();
97
98 let closure_chain = (move |x: &i32| {
99 *r1.lock().expect("mutex should not be poisoned") = *x * 2;
100 })
101 .and_then(move |_x: &i32| {
102 *r2.lock().expect("mutex should not be poisoned") += 10;
103 });
104
105 let value = 5;
106 println!("Initial value: {}", value);
107 closure_chain.accept(&value);
108 println!(
109 "Calculation result: {}",
110 *result.lock().expect("mutex should not be poisoned")
111 );
112 println!("Original value: {} (not modified)\n", value);
113
114 // ========================================================================
115 // Example 4: BoxConsumer factory methods
116 // ========================================================================
117 println!("Example 4: BoxConsumer factory methods");
118 println!("{}", "-".repeat(50));
119
120 // noop
121 println!("noop - does nothing:");
122 let noop = BoxConsumer::<i32>::noop();
123 let value = 42;
124 noop.accept(&value);
125 println!("Value: {}\n", value);
126
127 // print
128 print!("print - prints value: ");
129 let print = BoxConsumer::new(|x: &i32| println!("{}", x));
130 let value = 42;
131 print.accept(&value);
132 println!();
133
134 // print with prefix
135 let print_with = BoxConsumer::new(|x: &i32| println!("Value is: {}", x));
136 let value = 42;
137 print_with.accept(&value);
138 println!();
139
140 // ========================================================================
141 // Example 5: Conditional Consumer
142 // ========================================================================
143 println!("Example 5: Conditional Consumer");
144 println!("{}", "-".repeat(50));
145
146 // when
147 let mut check_positive =
148 BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x)).when(|x: &i32| *x > 0);
149
150 let positive = 5;
151 let negative = -5;
152 print!("Check {}: ", positive);
153 check_positive.accept(&positive);
154 print!("Check {}: ", negative);
155 check_positive.accept(&negative);
156 println!("(negative numbers not printed)\n");
157
158 // when().or_else()
159 let mut categorize = BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x))
160 .when(|x: &i32| *x > 0)
161 .or_else(|x: &i32| println!("Non-positive: {}", x));
162
163 let positive = 10;
164 let negative = -10;
165 categorize.accept(&positive);
166 categorize.accept(&negative);
167 println!();
168
169 // ========================================================================
170 // Example 6: ArcConsumer - multi-threaded sharing
171 // ========================================================================
172 println!("Example 6: ArcConsumer - multi-threaded sharing");
173 println!("{}", "-".repeat(50));
174
175 let shared = ArcConsumer::new(|x: &i32| println!("Processing value: {}", x * 2));
176
177 // Clone for another thread
178 let shared_clone = shared.clone();
179 let handle = thread::spawn(move || {
180 let value = 5;
181 let consumer = shared_clone;
182 consumer.accept(&value);
183 value
184 });
185
186 // Use in main thread
187 let value = 3;
188 let consumer = shared;
189 consumer.accept(&value);
190
191 let thread_result = handle.join().expect("thread should not panic");
192 println!("Thread result: {}\n", thread_result);
193
194 // ========================================================================
195 // Example 7: ArcConsumer composition (does not consume original consumer)
196 // ========================================================================
197 println!("Example 7: ArcConsumer composition (borrowing &self)");
198 println!("{}", "-".repeat(50));
199
200 let double = ArcConsumer::new(|x: &i32| println!("double: {}", x * 2));
201 let add_ten = ArcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
202
203 // Composition does not consume original consumer
204 let pipeline1 = double.and_then(add_ten.clone());
205 let pipeline2 = add_ten.and_then(double.clone());
206
207 let value1 = 5;
208 let p1 = pipeline1;
209 print!("pipeline1 processing 5: ");
210 p1.accept(&value1);
211
212 let value2 = 5;
213 let p2 = pipeline2;
214 print!("pipeline2 processing 5: ");
215 p2.accept(&value2);
216
217 // double and add_ten are still available
218 let value3 = 10;
219 let d = double;
220 print!("Original double still available, processing 10: ");
221 d.accept(&value3);
222 println!();
223
224 // ========================================================================
225 // Example 8: RcConsumer - single-threaded sharing
226 // ========================================================================
227 println!("Example 8: RcConsumer - single-threaded sharing");
228 println!("{}", "-".repeat(50));
229
230 let rc_consumer = RcConsumer::new(|x: &i32| println!("Processing: {}", x * 2));
231
232 // Clone multiple copies
233 let clone1 = rc_consumer.clone();
234 let clone2 = rc_consumer.clone();
235
236 let value1 = 5;
237 let c1 = clone1;
238 print!("clone1 processing 5: ");
239 c1.accept(&value1);
240
241 let value2 = 3;
242 let c2 = clone2;
243 print!("clone2 processing 3: ");
244 c2.accept(&value2);
245
246 let value3 = 7;
247 let c3 = rc_consumer;
248 print!("Original processing 7: ");
249 c3.accept(&value3);
250 println!();
251
252 // ========================================================================
253 // Example 9: RcConsumer composition (borrowing &self)
254 // ========================================================================
255 println!("Example 9: RcConsumer composition (borrowing &self)");
256 println!("{}", "-".repeat(50));
257
258 let double = RcConsumer::new(|x: &i32| println!("double: {}", x * 2));
259 let add_ten = RcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
260
261 let pipeline1 = double.and_then(add_ten.clone());
262 let pipeline2 = add_ten.and_then(double.clone());
263
264 let value1 = 5;
265 let p1 = pipeline1;
266 print!("pipeline1 processing 5: ");
267 p1.accept(&value1);
268
269 let value2 = 5;
270 let p2 = pipeline2;
271 print!("pipeline2 processing 5: ");
272 p2.accept(&value2);
273 println!();
274
275 // ========================================================================
276 // Example 10: Unified Consumer trait
277 // ========================================================================
278 println!("Example 10: Unified Consumer trait");
279 println!("{}", "-".repeat(50));
280
281 fn log_all<C: Consumer<i32>>(consumer: &mut C, values: &[i32]) {
282 for value in values.iter() {
283 consumer.accept(value);
284 }
285 }
286
287 let values = vec![1, 2, 3, 4, 5];
288
289 let mut box_con = BoxConsumer::new(|x: &i32| print!("{} ", x * 2));
290 print!("BoxConsumer processing {:?}: ", values);
291 log_all(&mut box_con, &values);
292 println!();
293
294 let mut arc_con = ArcConsumer::new(|x: &i32| print!("{} ", x * 2));
295 print!("ArcConsumer processing {:?}: ", values);
296 log_all(&mut arc_con, &values);
297 println!();
298
299 let mut rc_con = RcConsumer::new(|x: &i32| print!("{} ", x * 2));
300 print!("RcConsumer processing {:?}: ", values);
301 log_all(&mut rc_con, &values);
302 println!();
303
304 let mut closure = |x: &i32| print!("{} ", x * 2);
305 print!("Closure processing {:?}: ", values);
306 log_all(&mut closure, &values);
307 println!("\n");
308
309 // ========================================================================
310 // Example 11: Data validation and logging
311 // ========================================================================
312 println!("Example 11: Data validation and logging");
313 println!("{}", "-".repeat(50));
314
315 let validator = BoxConsumer::new(|x: &i32| {
316 let status = if *x >= 0 && *x <= 100 {
317 "valid"
318 } else {
319 "out of range"
320 };
321 println!("Validate {}: {}", x, status);
322 });
323
324 let logger = BoxConsumer::new(|x: &i32| {
325 println!("Log to file: value={}, square={}", x, x * x);
326 });
327
328 let pipeline = validator.and_then(logger);
329
330 let test_values = vec![-50, 30, 200];
331 for value in test_values {
332 pipeline.accept(&value);
333 }
334 println!();
335
336 // ========================================================================
337 // Example 12: String analysis
338 // ========================================================================
339 println!("Example 12: String analysis");
340 println!("{}", "-".repeat(50));
341
342 let string_analyzer = BoxConsumer::new(|s: &String| {
343 println!("Length: {}", s.len());
344 })
345 .and_then(|s: &String| {
346 println!("Lowercase: {}", s.to_lowercase());
347 })
348 .and_then(|s: &String| {
349 println!("Uppercase: {}", s.to_uppercase());
350 })
351 .and_then(|s: &String| {
352 let word_count = s.split_whitespace().count();
353 println!("Word count: {}", word_count);
354 });
355
356 let text = String::from("Hello World");
357 println!("Analyzing text: \"{}\"", text);
358 string_analyzer.accept(&text);
359 println!("Original text: \"{}\" (not modified)\n", text);
360
361 // ========================================================================
362 // Example 13: Type conversion
363 // ========================================================================
364 println!("Example 13: Type conversion");
365 println!("{}", "-".repeat(50));
366
367 // Closure -> BoxConsumer
368 let closure = |x: &i32| print!("Processing: {} ", x * 2);
369 let box_con = Consumer::into_box(closure);
370 let value = 5;
371 print!("Closure -> BoxConsumer: ");
372 box_con.accept(&value);
373 println!();
374
375 // Closure -> RcConsumer
376 let closure = |x: &i32| print!("Processing: {} ", x * 2);
377 let rc_con = Consumer::into_rc(closure);
378 let value = 5;
379 print!("Closure -> RcConsumer: ");
380 rc_con.accept(&value);
381 println!();
382
383 // Closure -> ArcConsumer
384 let closure = |x: &i32| print!("Processing: {} ", x * 2);
385 let arc_con = Consumer::into_arc(closure);
386 let value = 5;
387 print!("Closure -> ArcConsumer: ");
388 arc_con.accept(&value);
389 println!();
390
391 // BoxConsumer -> RcConsumer
392 let box_con = BoxConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
393 let rc_con = box_con.into_rc();
394 let value = 5;
395 print!("BoxConsumer -> RcConsumer: ");
396 rc_con.accept(&value);
397 println!();
398
399 // RcConsumer -> BoxConsumer
400 let rc_con = RcConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
401 let box_con = rc_con.into_box();
402 let value = 5;
403 print!("RcConsumer -> BoxConsumer: ");
404 box_con.accept(&value);
405 println!("\n");
406
407 // ========================================================================
408 // Example 14: Custom types
409 // ========================================================================
410 println!("Example 14: Custom types");
411 println!("{}", "-".repeat(50));
412
413 #[derive(Debug, Clone)]
414 struct Point {
415 x: i32,
416 y: i32,
417 }
418
419 let analyzer = BoxConsumer::new(|p: &Point| {
420 println!("Point coordinates: ({}, {})", p.x, p.y);
421 })
422 .and_then(|p: &Point| {
423 let distance = ((p.x * p.x + p.y * p.y) as f64).sqrt();
424 println!("Distance from origin: {:.2}", distance);
425 })
426 .and_then(|p: &Point| {
427 let quadrant = match (p.x >= 0, p.y >= 0) {
428 (true, true) => "First quadrant",
429 (false, true) => "Second quadrant",
430 (false, false) => "Third quadrant",
431 (true, false) => "Fourth quadrant",
432 };
433 println!("Quadrant: {}", quadrant);
434 });
435
436 let point = Point { x: 3, y: 4 };
437 println!("Analyzing point: {:?}", point);
438 analyzer.accept(&point);
439 println!("Original point: {:?} (not modified)\n", point);
440
441 // ========================================================================
442 // Example 15: Data collection and statistics
443 // ========================================================================
444 println!("Example 15: Data collection and statistics");
445 println!("{}", "-".repeat(50));
446
447 let sum = Arc::new(Mutex::new(0));
448 let count = Arc::new(Mutex::new(0));
449 let sum_clone = sum.clone();
450 let count_clone = count.clone();
451
452 let collector = BoxConsumer::new(move |x: &i32| {
453 *sum_clone.lock().expect("mutex should not be poisoned") += *x;
454 *count_clone.lock().expect("mutex should not be poisoned") += 1;
455 });
456
457 let numbers = vec![10, 20, 30, 40, 50];
458 println!("Numbers: {:?}", numbers);
459 for num in &numbers {
460 collector.accept(num);
461 }
462
463 let total = *sum.lock().expect("mutex should not be poisoned");
464 let cnt = *count.lock().expect("mutex should not be poisoned");
465 println!("Sum: {}", total);
466 println!("Count: {}", cnt);
467 println!("Average: {:.2}\n", total as f64 / cnt as f64);
468
469 println!("=== All examples completed ===");
470 println!("\nTip: For value modification functionality, please refer to mutator_demo.rs");
471}Sourcefn into_fn(self) -> impl Fn(&T)where
Self: Sized + 'static,
fn into_fn(self) -> impl Fn(&T)where
Self: Sized + 'static,
Convert to closure
⚠️ Consumes self: The original consumer will be unavailable after
calling this method.
Converts a non-mutating consumer to a closure that can be used directly in
places where the standard library requires Fn.
§Returns
Returns a closure implementing Fn(&T)
§Examples
use qubit_function::{Consumer, BoxConsumer};
let consumer = BoxConsumer::new(|x: &i32| {
println!("Value: {}", x);
});
let func = consumer.into_fn();
func(&5);Examples found in repository?
25fn main() {
26 println!("=== Consumer into_fn/to_fn Usage Examples ===\n");
27
28 // Example 1: Using BoxConsumer::into_fn to pass to standard library's map
29 println!("1. BoxConsumer::into_fn used with Iterator::for_each");
30 let log = Arc::new(Mutex::new(Vec::new()));
31 let l = log.clone();
32 let consumer = BoxConsumer::new(move |x: &i32| {
33 l.lock().expect("mutex should not be poisoned").push(*x * 2);
34 });
35
36 // Convert consumer to closure and pass to for_each
37 [1, 2, 3, 4, 5].iter().for_each(consumer.into_fn());
38 println!(
39 " Result: {:?}\n",
40 *log.lock().expect("mutex should not be poisoned")
41 );
42
43 // Example 2: Using ArcConsumer::to_fn can be used multiple times
44 println!("2. ArcConsumer::to_fn can be used multiple times");
45 let log2 = Arc::new(Mutex::new(Vec::new()));
46 let l2 = log2.clone();
47 let consumer2 = ArcConsumer::new(move |x: &i32| {
48 l2.lock()
49 .expect("mutex should not be poisoned")
50 .push(*x + 10);
51 });
52
53 // to_fn doesn't consume consumer, can be called multiple times
54 [1, 2, 3].iter().for_each(consumer2.to_fn());
55 println!(
56 " First time: {:?}",
57 *log2.lock().expect("mutex should not be poisoned")
58 );
59
60 [4, 5].iter().for_each(consumer2.to_fn());
61 println!(
62 " Second time: {:?}\n",
63 *log2.lock().expect("mutex should not be poisoned")
64 );
65
66 // Example 3: Using RcConsumer::to_fn
67 println!("3. RcConsumer::to_fn used for single-threaded scenarios");
68 let log3 = Rc::new(RefCell::new(Vec::new()));
69 let l3 = log3.clone();
70 let consumer3 = RcConsumer::new(move |x: &i32| {
71 l3.borrow_mut().push(*x * 3);
72 });
73
74 [1, 2, 3, 4].iter().for_each(consumer3.to_fn());
75 println!(" Result: {:?}\n", *log3.borrow());
76
77 // Example 4: Using in custom functions
78 println!("4. Using in custom functions");
79 fn process_items<F>(items: Vec<i32>, consumer: F)
80 where
81 F: FnMut(&i32),
82 {
83 items.iter().for_each(consumer);
84 }
85
86 let log4 = Arc::new(Mutex::new(Vec::new()));
87 let l4 = log4.clone();
88 let consumer4 = BoxConsumer::new(move |x: &i32| {
89 l4.lock()
90 .expect("mutex should not be poisoned")
91 .push(*x * 5);
92 });
93
94 // Use into_fn to convert Consumer to closure and pass to function
95 process_items(vec![1, 2, 3], consumer4.into_fn());
96 println!(
97 " Result: {:?}\n",
98 *log4.lock().expect("mutex should not be poisoned")
99 );
100
101 // Example 5: Using into_fn after chained operations
102 println!("5. Using into_fn after chained operations");
103 let log5 = Arc::new(Mutex::new(Vec::new()));
104 let l5 = log5.clone();
105 let l6 = log5.clone();
106
107 let chained = BoxConsumer::new(move |x: &i32| {
108 l5.lock()
109 .expect("mutex should not be poisoned")
110 .push(format!("A: {}", x));
111 })
112 .and_then(move |x: &i32| {
113 l6.lock()
114 .expect("mutex should not be poisoned")
115 .push(format!("B: {}", x));
116 });
117
118 [1, 2].iter().for_each(chained.into_fn());
119 println!(
120 " Result: {:?}\n",
121 *log5.lock().expect("mutex should not be poisoned")
122 );
123
124 println!("=== Demo Complete ===");
125}Sourcefn into_once(self) -> BoxConsumerOnce<T>where
Self: Sized + 'static,
fn into_once(self) -> BoxConsumerOnce<T>where
Self: Sized + 'static,
Convert to ConsumerOnce
⚠️ Consumes self: The original consumer will be unavailable after calling this method.
Converts a reusable non-mutating consumer to a one-time consumer that consumes itself on use.
This enables passing Consumer to functions that require ConsumerOnce.
§Returns
Returns a BoxConsumerOnce<T>
§Examples
use qubit_function::{Consumer, ConsumerOnce, BoxConsumer};
fn takes_once<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
consumer.accept(value);
}
let consumer = BoxConsumer::new(|x: &i32| println!("{}", x));
takes_once(consumer.into_once(), &5);Sourcefn to_box(&self) -> BoxConsumer<T>where
Self: Clone + 'static,
fn to_box(&self) -> BoxConsumer<T>where
Self: Clone + 'static,
Non-consuming conversion to BoxConsumer
⚠️ Does NOT consume self: This method clones self and returns a
boxed non-mutating consumer that calls the cloned consumer. Requires
Self: Clone so it can be called through an immutable reference.
§Returns
Returns the wrapped BoxConsumer<T>
Sourcefn to_rc(&self) -> RcConsumer<T>where
Self: Clone + 'static,
fn to_rc(&self) -> RcConsumer<T>where
Self: Clone + 'static,
Non-consuming conversion to RcConsumer
⚠️ Does NOT consume self: Clones self and returns an
RcConsumer that forwards to the cloned consumer. Requires
Self: Clone.
§Returns
Returns the wrapped RcConsumer<T>
Sourcefn to_arc(&self) -> ArcConsumer<T>
fn to_arc(&self) -> ArcConsumer<T>
Non-consuming conversion to ArcConsumer
⚠️ Does NOT consume self: Clones self and returns an
ArcConsumer. Requires Self: Clone + Send + Sync so the result
is thread-safe.
§Returns
Returns the wrapped ArcConsumer<T>
Sourcefn to_fn(&self) -> impl Fn(&T)where
Self: Clone + 'static,
fn to_fn(&self) -> impl Fn(&T)where
Self: Clone + 'static,
Non-consuming conversion to a boxed closure
⚠️ Does NOT consume self: Returns a closure which calls a cloned
copy of the consumer. Requires Self: Clone.
§Returns
Returns a closure implementing Fn(&T) which forwards to the cloned
consumer.
Examples found in repository?
25fn main() {
26 println!("=== Consumer into_fn/to_fn Usage Examples ===\n");
27
28 // Example 1: Using BoxConsumer::into_fn to pass to standard library's map
29 println!("1. BoxConsumer::into_fn used with Iterator::for_each");
30 let log = Arc::new(Mutex::new(Vec::new()));
31 let l = log.clone();
32 let consumer = BoxConsumer::new(move |x: &i32| {
33 l.lock().expect("mutex should not be poisoned").push(*x * 2);
34 });
35
36 // Convert consumer to closure and pass to for_each
37 [1, 2, 3, 4, 5].iter().for_each(consumer.into_fn());
38 println!(
39 " Result: {:?}\n",
40 *log.lock().expect("mutex should not be poisoned")
41 );
42
43 // Example 2: Using ArcConsumer::to_fn can be used multiple times
44 println!("2. ArcConsumer::to_fn can be used multiple times");
45 let log2 = Arc::new(Mutex::new(Vec::new()));
46 let l2 = log2.clone();
47 let consumer2 = ArcConsumer::new(move |x: &i32| {
48 l2.lock()
49 .expect("mutex should not be poisoned")
50 .push(*x + 10);
51 });
52
53 // to_fn doesn't consume consumer, can be called multiple times
54 [1, 2, 3].iter().for_each(consumer2.to_fn());
55 println!(
56 " First time: {:?}",
57 *log2.lock().expect("mutex should not be poisoned")
58 );
59
60 [4, 5].iter().for_each(consumer2.to_fn());
61 println!(
62 " Second time: {:?}\n",
63 *log2.lock().expect("mutex should not be poisoned")
64 );
65
66 // Example 3: Using RcConsumer::to_fn
67 println!("3. RcConsumer::to_fn used for single-threaded scenarios");
68 let log3 = Rc::new(RefCell::new(Vec::new()));
69 let l3 = log3.clone();
70 let consumer3 = RcConsumer::new(move |x: &i32| {
71 l3.borrow_mut().push(*x * 3);
72 });
73
74 [1, 2, 3, 4].iter().for_each(consumer3.to_fn());
75 println!(" Result: {:?}\n", *log3.borrow());
76
77 // Example 4: Using in custom functions
78 println!("4. Using in custom functions");
79 fn process_items<F>(items: Vec<i32>, consumer: F)
80 where
81 F: FnMut(&i32),
82 {
83 items.iter().for_each(consumer);
84 }
85
86 let log4 = Arc::new(Mutex::new(Vec::new()));
87 let l4 = log4.clone();
88 let consumer4 = BoxConsumer::new(move |x: &i32| {
89 l4.lock()
90 .expect("mutex should not be poisoned")
91 .push(*x * 5);
92 });
93
94 // Use into_fn to convert Consumer to closure and pass to function
95 process_items(vec![1, 2, 3], consumer4.into_fn());
96 println!(
97 " Result: {:?}\n",
98 *log4.lock().expect("mutex should not be poisoned")
99 );
100
101 // Example 5: Using into_fn after chained operations
102 println!("5. Using into_fn after chained operations");
103 let log5 = Arc::new(Mutex::new(Vec::new()));
104 let l5 = log5.clone();
105 let l6 = log5.clone();
106
107 let chained = BoxConsumer::new(move |x: &i32| {
108 l5.lock()
109 .expect("mutex should not be poisoned")
110 .push(format!("A: {}", x));
111 })
112 .and_then(move |x: &i32| {
113 l6.lock()
114 .expect("mutex should not be poisoned")
115 .push(format!("B: {}", x));
116 });
117
118 [1, 2].iter().for_each(chained.into_fn());
119 println!(
120 " Result: {:?}\n",
121 *log5.lock().expect("mutex should not be poisoned")
122 );
123
124 println!("=== Demo Complete ===");
125}Sourcefn to_once(&self) -> BoxConsumerOnce<T>where
Self: Clone + 'static,
fn to_once(&self) -> BoxConsumerOnce<T>where
Self: Clone + 'static,
Convert to ConsumerOnce without consuming self
⚠️ Requires Clone: This method requires Self to implement Clone.
Clones the current consumer and converts the clone to a one-time consumer.
§Returns
Returns a BoxConsumerOnce<T>
§Examples
use qubit_function::{Consumer, ConsumerOnce, ArcConsumer};
fn takes_once<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
consumer.accept(value);
}
let consumer = ArcConsumer::new(|x: &i32| println!("{}", x));
takes_once(consumer.to_once(), &5);