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().unwrap().push(*x * 2);
66 })
67 .and_then(move |x: &i32| {
68 r2.lock().unwrap().push(*x + 10);
69 })
70 .and_then(move |x: &i32| {
71 r3.lock().unwrap().push(*x);
72 println!("Processing value: {}", x);
73 });
74
75 let value = 5;
76 println!("Initial value: {}", value);
77 chained.accept(&value);
78 println!("Collected results: {:?}", *results.lock().unwrap());
79 println!("Original value: {} (not modified)\n", value);
80
81 // ========================================================================
82 // Example 3: Closure extension methods
83 // ========================================================================
84 println!("Example 3: Direct use of extension methods on closures");
85 println!("{}", "-".repeat(50));
86
87 let result = Arc::new(Mutex::new(0));
88 let r1 = result.clone();
89 let r2 = result.clone();
90
91 let closure_chain = (move |x: &i32| {
92 *r1.lock().unwrap() = *x * 2;
93 })
94 .and_then(move |_x: &i32| {
95 *r2.lock().unwrap() += 10;
96 });
97
98 let value = 5;
99 println!("Initial value: {}", value);
100 closure_chain.accept(&value);
101 println!("Calculation result: {}", *result.lock().unwrap());
102 println!("Original value: {} (not modified)\n", value);
103
104 // ========================================================================
105 // Example 4: BoxConsumer factory methods
106 // ========================================================================
107 println!("Example 4: BoxConsumer factory methods");
108 println!("{}", "-".repeat(50));
109
110 // noop
111 println!("noop - does nothing:");
112 let noop = BoxConsumer::<i32>::noop();
113 let value = 42;
114 noop.accept(&value);
115 println!("Value: {}\n", value);
116
117 // print
118 print!("print - prints value: ");
119 let print = BoxConsumer::new(|x: &i32| println!("{}", x));
120 let value = 42;
121 print.accept(&value);
122 println!();
123
124 // print with prefix
125 let print_with = BoxConsumer::new(|x: &i32| println!("Value is: {}", x));
126 let value = 42;
127 print_with.accept(&value);
128 println!();
129
130 // ========================================================================
131 // Example 5: Conditional Consumer
132 // ========================================================================
133 println!("Example 5: Conditional Consumer");
134 println!("{}", "-".repeat(50));
135
136 // when
137 let mut check_positive =
138 BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x)).when(|x: &i32| *x > 0);
139
140 let positive = 5;
141 let negative = -5;
142 print!("Check {}: ", positive);
143 check_positive.accept(&positive);
144 print!("Check {}: ", negative);
145 check_positive.accept(&negative);
146 println!("(negative numbers not printed)\n");
147
148 // when().or_else()
149 let mut categorize = BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x))
150 .when(|x: &i32| *x > 0)
151 .or_else(|x: &i32| println!("Non-positive: {}", x));
152
153 let positive = 10;
154 let negative = -10;
155 categorize.accept(&positive);
156 categorize.accept(&negative);
157 println!();
158
159 // ========================================================================
160 // Example 6: ArcConsumer - multi-threaded sharing
161 // ========================================================================
162 println!("Example 6: ArcConsumer - multi-threaded sharing");
163 println!("{}", "-".repeat(50));
164
165 let shared = ArcConsumer::new(|x: &i32| println!("Processing value: {}", x * 2));
166
167 // Clone for another thread
168 let shared_clone = shared.clone();
169 let handle = thread::spawn(move || {
170 let value = 5;
171 let consumer = shared_clone;
172 consumer.accept(&value);
173 value
174 });
175
176 // Use in main thread
177 let value = 3;
178 let consumer = shared;
179 consumer.accept(&value);
180
181 let thread_result = handle.join().unwrap();
182 println!("Thread result: {}\n", thread_result);
183
184 // ========================================================================
185 // Example 7: ArcConsumer composition (does not consume original consumer)
186 // ========================================================================
187 println!("Example 7: ArcConsumer composition (borrowing &self)");
188 println!("{}", "-".repeat(50));
189
190 let double = ArcConsumer::new(|x: &i32| println!("double: {}", x * 2));
191 let add_ten = ArcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
192
193 // Composition does not consume original consumer
194 let pipeline1 = double.and_then(add_ten.clone());
195 let pipeline2 = add_ten.and_then(double.clone());
196
197 let value1 = 5;
198 let p1 = pipeline1;
199 print!("pipeline1 processing 5: ");
200 p1.accept(&value1);
201
202 let value2 = 5;
203 let p2 = pipeline2;
204 print!("pipeline2 processing 5: ");
205 p2.accept(&value2);
206
207 // double and add_ten are still available
208 let value3 = 10;
209 let d = double;
210 print!("Original double still available, processing 10: ");
211 d.accept(&value3);
212 println!();
213
214 // ========================================================================
215 // Example 8: RcConsumer - single-threaded sharing
216 // ========================================================================
217 println!("Example 8: RcConsumer - single-threaded sharing");
218 println!("{}", "-".repeat(50));
219
220 let rc_consumer = RcConsumer::new(|x: &i32| println!("Processing: {}", x * 2));
221
222 // Clone multiple copies
223 let clone1 = rc_consumer.clone();
224 let clone2 = rc_consumer.clone();
225
226 let value1 = 5;
227 let c1 = clone1;
228 print!("clone1 processing 5: ");
229 c1.accept(&value1);
230
231 let value2 = 3;
232 let c2 = clone2;
233 print!("clone2 processing 3: ");
234 c2.accept(&value2);
235
236 let value3 = 7;
237 let c3 = rc_consumer;
238 print!("Original processing 7: ");
239 c3.accept(&value3);
240 println!();
241
242 // ========================================================================
243 // Example 9: RcConsumer composition (borrowing &self)
244 // ========================================================================
245 println!("Example 9: RcConsumer composition (borrowing &self)");
246 println!("{}", "-".repeat(50));
247
248 let double = RcConsumer::new(|x: &i32| println!("double: {}", x * 2));
249 let add_ten = RcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
250
251 let pipeline1 = double.and_then(add_ten.clone());
252 let pipeline2 = add_ten.and_then(double.clone());
253
254 let value1 = 5;
255 let p1 = pipeline1;
256 print!("pipeline1 processing 5: ");
257 p1.accept(&value1);
258
259 let value2 = 5;
260 let p2 = pipeline2;
261 print!("pipeline2 processing 5: ");
262 p2.accept(&value2);
263 println!();
264
265 // ========================================================================
266 // Example 10: Unified Consumer trait
267 // ========================================================================
268 println!("Example 10: Unified Consumer trait");
269 println!("{}", "-".repeat(50));
270
271 fn log_all<C: Consumer<i32>>(consumer: &mut C, values: &[i32]) {
272 for value in values.iter() {
273 consumer.accept(value);
274 }
275 }
276
277 let values = vec![1, 2, 3, 4, 5];
278
279 let mut box_con = BoxConsumer::new(|x: &i32| print!("{} ", x * 2));
280 print!("BoxConsumer processing {:?}: ", values);
281 log_all(&mut box_con, &values);
282 println!();
283
284 let mut arc_con = ArcConsumer::new(|x: &i32| print!("{} ", x * 2));
285 print!("ArcConsumer processing {:?}: ", values);
286 log_all(&mut arc_con, &values);
287 println!();
288
289 let mut rc_con = RcConsumer::new(|x: &i32| print!("{} ", x * 2));
290 print!("RcConsumer processing {:?}: ", values);
291 log_all(&mut rc_con, &values);
292 println!();
293
294 let mut closure = |x: &i32| print!("{} ", x * 2);
295 print!("Closure processing {:?}: ", values);
296 log_all(&mut closure, &values);
297 println!("\n");
298
299 // ========================================================================
300 // Example 11: Data validation and logging
301 // ========================================================================
302 println!("Example 11: Data validation and logging");
303 println!("{}", "-".repeat(50));
304
305 let validator = BoxConsumer::new(|x: &i32| {
306 let status = if *x >= 0 && *x <= 100 {
307 "valid"
308 } else {
309 "out of range"
310 };
311 println!("Validate {}: {}", x, status);
312 });
313
314 let logger = BoxConsumer::new(|x: &i32| {
315 println!("Log to file: value={}, square={}", x, x * x);
316 });
317
318 let pipeline = validator.and_then(logger);
319
320 let test_values = vec![-50, 30, 200];
321 for value in test_values {
322 pipeline.accept(&value);
323 }
324 println!();
325
326 // ========================================================================
327 // Example 12: String analysis
328 // ========================================================================
329 println!("Example 12: String analysis");
330 println!("{}", "-".repeat(50));
331
332 let string_analyzer = BoxConsumer::new(|s: &String| {
333 println!("Length: {}", s.len());
334 })
335 .and_then(|s: &String| {
336 println!("Lowercase: {}", s.to_lowercase());
337 })
338 .and_then(|s: &String| {
339 println!("Uppercase: {}", s.to_uppercase());
340 })
341 .and_then(|s: &String| {
342 let word_count = s.split_whitespace().count();
343 println!("Word count: {}", word_count);
344 });
345
346 let text = String::from("Hello World");
347 println!("Analyzing text: \"{}\"", text);
348 string_analyzer.accept(&text);
349 println!("Original text: \"{}\" (not modified)\n", text);
350
351 // ========================================================================
352 // Example 13: Type conversion
353 // ========================================================================
354 println!("Example 13: Type conversion");
355 println!("{}", "-".repeat(50));
356
357 // Closure -> BoxConsumer
358 let closure = |x: &i32| print!("Processing: {} ", x * 2);
359 let box_con = Consumer::into_box(closure);
360 let value = 5;
361 print!("Closure -> BoxConsumer: ");
362 box_con.accept(&value);
363 println!();
364
365 // Closure -> RcConsumer
366 let closure = |x: &i32| print!("Processing: {} ", x * 2);
367 let rc_con = Consumer::into_rc(closure);
368 let value = 5;
369 print!("Closure -> RcConsumer: ");
370 rc_con.accept(&value);
371 println!();
372
373 // Closure -> ArcConsumer
374 let closure = |x: &i32| print!("Processing: {} ", x * 2);
375 let arc_con = Consumer::into_arc(closure);
376 let value = 5;
377 print!("Closure -> ArcConsumer: ");
378 arc_con.accept(&value);
379 println!();
380
381 // BoxConsumer -> RcConsumer
382 let box_con = BoxConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
383 let rc_con = box_con.into_rc();
384 let value = 5;
385 print!("BoxConsumer -> RcConsumer: ");
386 rc_con.accept(&value);
387 println!();
388
389 // RcConsumer -> BoxConsumer
390 let rc_con = RcConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
391 let box_con = rc_con.into_box();
392 let value = 5;
393 print!("RcConsumer -> BoxConsumer: ");
394 box_con.accept(&value);
395 println!("\n");
396
397 // ========================================================================
398 // Example 14: Custom types
399 // ========================================================================
400 println!("Example 14: Custom types");
401 println!("{}", "-".repeat(50));
402
403 #[derive(Debug, Clone)]
404 struct Point {
405 x: i32,
406 y: i32,
407 }
408
409 let analyzer = BoxConsumer::new(|p: &Point| {
410 println!("Point coordinates: ({}, {})", p.x, p.y);
411 })
412 .and_then(|p: &Point| {
413 let distance = ((p.x * p.x + p.y * p.y) as f64).sqrt();
414 println!("Distance from origin: {:.2}", distance);
415 })
416 .and_then(|p: &Point| {
417 let quadrant = match (p.x >= 0, p.y >= 0) {
418 (true, true) => "First quadrant",
419 (false, true) => "Second quadrant",
420 (false, false) => "Third quadrant",
421 (true, false) => "Fourth quadrant",
422 };
423 println!("Quadrant: {}", quadrant);
424 });
425
426 let point = Point { x: 3, y: 4 };
427 println!("Analyzing point: {:?}", point);
428 analyzer.accept(&point);
429 println!("Original point: {:?} (not modified)\n", point);
430
431 // ========================================================================
432 // Example 15: Data collection and statistics
433 // ========================================================================
434 println!("Example 15: Data collection and statistics");
435 println!("{}", "-".repeat(50));
436
437 let sum = Arc::new(Mutex::new(0));
438 let count = Arc::new(Mutex::new(0));
439 let sum_clone = sum.clone();
440 let count_clone = count.clone();
441
442 let collector = BoxConsumer::new(move |x: &i32| {
443 *sum_clone.lock().unwrap() += *x;
444 *count_clone.lock().unwrap() += 1;
445 });
446
447 let numbers = vec![10, 20, 30, 40, 50];
448 println!("Numbers: {:?}", numbers);
449 for num in &numbers {
450 collector.accept(num);
451 }
452
453 let total = *sum.lock().unwrap();
454 let cnt = *count.lock().unwrap();
455 println!("Sum: {}", total);
456 println!("Count: {}", cnt);
457 println!("Average: {:.2}\n", total as f64 / cnt as f64);
458
459 println!("=== All examples completed ===");
460 println!("\nTip: For value modification functionality, please refer to mutator_demo.rs");
461}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().unwrap().push(*x * 2);
66 })
67 .and_then(move |x: &i32| {
68 r2.lock().unwrap().push(*x + 10);
69 })
70 .and_then(move |x: &i32| {
71 r3.lock().unwrap().push(*x);
72 println!("Processing value: {}", x);
73 });
74
75 let value = 5;
76 println!("Initial value: {}", value);
77 chained.accept(&value);
78 println!("Collected results: {:?}", *results.lock().unwrap());
79 println!("Original value: {} (not modified)\n", value);
80
81 // ========================================================================
82 // Example 3: Closure extension methods
83 // ========================================================================
84 println!("Example 3: Direct use of extension methods on closures");
85 println!("{}", "-".repeat(50));
86
87 let result = Arc::new(Mutex::new(0));
88 let r1 = result.clone();
89 let r2 = result.clone();
90
91 let closure_chain = (move |x: &i32| {
92 *r1.lock().unwrap() = *x * 2;
93 })
94 .and_then(move |_x: &i32| {
95 *r2.lock().unwrap() += 10;
96 });
97
98 let value = 5;
99 println!("Initial value: {}", value);
100 closure_chain.accept(&value);
101 println!("Calculation result: {}", *result.lock().unwrap());
102 println!("Original value: {} (not modified)\n", value);
103
104 // ========================================================================
105 // Example 4: BoxConsumer factory methods
106 // ========================================================================
107 println!("Example 4: BoxConsumer factory methods");
108 println!("{}", "-".repeat(50));
109
110 // noop
111 println!("noop - does nothing:");
112 let noop = BoxConsumer::<i32>::noop();
113 let value = 42;
114 noop.accept(&value);
115 println!("Value: {}\n", value);
116
117 // print
118 print!("print - prints value: ");
119 let print = BoxConsumer::new(|x: &i32| println!("{}", x));
120 let value = 42;
121 print.accept(&value);
122 println!();
123
124 // print with prefix
125 let print_with = BoxConsumer::new(|x: &i32| println!("Value is: {}", x));
126 let value = 42;
127 print_with.accept(&value);
128 println!();
129
130 // ========================================================================
131 // Example 5: Conditional Consumer
132 // ========================================================================
133 println!("Example 5: Conditional Consumer");
134 println!("{}", "-".repeat(50));
135
136 // when
137 let mut check_positive =
138 BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x)).when(|x: &i32| *x > 0);
139
140 let positive = 5;
141 let negative = -5;
142 print!("Check {}: ", positive);
143 check_positive.accept(&positive);
144 print!("Check {}: ", negative);
145 check_positive.accept(&negative);
146 println!("(negative numbers not printed)\n");
147
148 // when().or_else()
149 let mut categorize = BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x))
150 .when(|x: &i32| *x > 0)
151 .or_else(|x: &i32| println!("Non-positive: {}", x));
152
153 let positive = 10;
154 let negative = -10;
155 categorize.accept(&positive);
156 categorize.accept(&negative);
157 println!();
158
159 // ========================================================================
160 // Example 6: ArcConsumer - multi-threaded sharing
161 // ========================================================================
162 println!("Example 6: ArcConsumer - multi-threaded sharing");
163 println!("{}", "-".repeat(50));
164
165 let shared = ArcConsumer::new(|x: &i32| println!("Processing value: {}", x * 2));
166
167 // Clone for another thread
168 let shared_clone = shared.clone();
169 let handle = thread::spawn(move || {
170 let value = 5;
171 let consumer = shared_clone;
172 consumer.accept(&value);
173 value
174 });
175
176 // Use in main thread
177 let value = 3;
178 let consumer = shared;
179 consumer.accept(&value);
180
181 let thread_result = handle.join().unwrap();
182 println!("Thread result: {}\n", thread_result);
183
184 // ========================================================================
185 // Example 7: ArcConsumer composition (does not consume original consumer)
186 // ========================================================================
187 println!("Example 7: ArcConsumer composition (borrowing &self)");
188 println!("{}", "-".repeat(50));
189
190 let double = ArcConsumer::new(|x: &i32| println!("double: {}", x * 2));
191 let add_ten = ArcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
192
193 // Composition does not consume original consumer
194 let pipeline1 = double.and_then(add_ten.clone());
195 let pipeline2 = add_ten.and_then(double.clone());
196
197 let value1 = 5;
198 let p1 = pipeline1;
199 print!("pipeline1 processing 5: ");
200 p1.accept(&value1);
201
202 let value2 = 5;
203 let p2 = pipeline2;
204 print!("pipeline2 processing 5: ");
205 p2.accept(&value2);
206
207 // double and add_ten are still available
208 let value3 = 10;
209 let d = double;
210 print!("Original double still available, processing 10: ");
211 d.accept(&value3);
212 println!();
213
214 // ========================================================================
215 // Example 8: RcConsumer - single-threaded sharing
216 // ========================================================================
217 println!("Example 8: RcConsumer - single-threaded sharing");
218 println!("{}", "-".repeat(50));
219
220 let rc_consumer = RcConsumer::new(|x: &i32| println!("Processing: {}", x * 2));
221
222 // Clone multiple copies
223 let clone1 = rc_consumer.clone();
224 let clone2 = rc_consumer.clone();
225
226 let value1 = 5;
227 let c1 = clone1;
228 print!("clone1 processing 5: ");
229 c1.accept(&value1);
230
231 let value2 = 3;
232 let c2 = clone2;
233 print!("clone2 processing 3: ");
234 c2.accept(&value2);
235
236 let value3 = 7;
237 let c3 = rc_consumer;
238 print!("Original processing 7: ");
239 c3.accept(&value3);
240 println!();
241
242 // ========================================================================
243 // Example 9: RcConsumer composition (borrowing &self)
244 // ========================================================================
245 println!("Example 9: RcConsumer composition (borrowing &self)");
246 println!("{}", "-".repeat(50));
247
248 let double = RcConsumer::new(|x: &i32| println!("double: {}", x * 2));
249 let add_ten = RcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
250
251 let pipeline1 = double.and_then(add_ten.clone());
252 let pipeline2 = add_ten.and_then(double.clone());
253
254 let value1 = 5;
255 let p1 = pipeline1;
256 print!("pipeline1 processing 5: ");
257 p1.accept(&value1);
258
259 let value2 = 5;
260 let p2 = pipeline2;
261 print!("pipeline2 processing 5: ");
262 p2.accept(&value2);
263 println!();
264
265 // ========================================================================
266 // Example 10: Unified Consumer trait
267 // ========================================================================
268 println!("Example 10: Unified Consumer trait");
269 println!("{}", "-".repeat(50));
270
271 fn log_all<C: Consumer<i32>>(consumer: &mut C, values: &[i32]) {
272 for value in values.iter() {
273 consumer.accept(value);
274 }
275 }
276
277 let values = vec![1, 2, 3, 4, 5];
278
279 let mut box_con = BoxConsumer::new(|x: &i32| print!("{} ", x * 2));
280 print!("BoxConsumer processing {:?}: ", values);
281 log_all(&mut box_con, &values);
282 println!();
283
284 let mut arc_con = ArcConsumer::new(|x: &i32| print!("{} ", x * 2));
285 print!("ArcConsumer processing {:?}: ", values);
286 log_all(&mut arc_con, &values);
287 println!();
288
289 let mut rc_con = RcConsumer::new(|x: &i32| print!("{} ", x * 2));
290 print!("RcConsumer processing {:?}: ", values);
291 log_all(&mut rc_con, &values);
292 println!();
293
294 let mut closure = |x: &i32| print!("{} ", x * 2);
295 print!("Closure processing {:?}: ", values);
296 log_all(&mut closure, &values);
297 println!("\n");
298
299 // ========================================================================
300 // Example 11: Data validation and logging
301 // ========================================================================
302 println!("Example 11: Data validation and logging");
303 println!("{}", "-".repeat(50));
304
305 let validator = BoxConsumer::new(|x: &i32| {
306 let status = if *x >= 0 && *x <= 100 {
307 "valid"
308 } else {
309 "out of range"
310 };
311 println!("Validate {}: {}", x, status);
312 });
313
314 let logger = BoxConsumer::new(|x: &i32| {
315 println!("Log to file: value={}, square={}", x, x * x);
316 });
317
318 let pipeline = validator.and_then(logger);
319
320 let test_values = vec![-50, 30, 200];
321 for value in test_values {
322 pipeline.accept(&value);
323 }
324 println!();
325
326 // ========================================================================
327 // Example 12: String analysis
328 // ========================================================================
329 println!("Example 12: String analysis");
330 println!("{}", "-".repeat(50));
331
332 let string_analyzer = BoxConsumer::new(|s: &String| {
333 println!("Length: {}", s.len());
334 })
335 .and_then(|s: &String| {
336 println!("Lowercase: {}", s.to_lowercase());
337 })
338 .and_then(|s: &String| {
339 println!("Uppercase: {}", s.to_uppercase());
340 })
341 .and_then(|s: &String| {
342 let word_count = s.split_whitespace().count();
343 println!("Word count: {}", word_count);
344 });
345
346 let text = String::from("Hello World");
347 println!("Analyzing text: \"{}\"", text);
348 string_analyzer.accept(&text);
349 println!("Original text: \"{}\" (not modified)\n", text);
350
351 // ========================================================================
352 // Example 13: Type conversion
353 // ========================================================================
354 println!("Example 13: Type conversion");
355 println!("{}", "-".repeat(50));
356
357 // Closure -> BoxConsumer
358 let closure = |x: &i32| print!("Processing: {} ", x * 2);
359 let box_con = Consumer::into_box(closure);
360 let value = 5;
361 print!("Closure -> BoxConsumer: ");
362 box_con.accept(&value);
363 println!();
364
365 // Closure -> RcConsumer
366 let closure = |x: &i32| print!("Processing: {} ", x * 2);
367 let rc_con = Consumer::into_rc(closure);
368 let value = 5;
369 print!("Closure -> RcConsumer: ");
370 rc_con.accept(&value);
371 println!();
372
373 // Closure -> ArcConsumer
374 let closure = |x: &i32| print!("Processing: {} ", x * 2);
375 let arc_con = Consumer::into_arc(closure);
376 let value = 5;
377 print!("Closure -> ArcConsumer: ");
378 arc_con.accept(&value);
379 println!();
380
381 // BoxConsumer -> RcConsumer
382 let box_con = BoxConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
383 let rc_con = box_con.into_rc();
384 let value = 5;
385 print!("BoxConsumer -> RcConsumer: ");
386 rc_con.accept(&value);
387 println!();
388
389 // RcConsumer -> BoxConsumer
390 let rc_con = RcConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
391 let box_con = rc_con.into_box();
392 let value = 5;
393 print!("RcConsumer -> BoxConsumer: ");
394 box_con.accept(&value);
395 println!("\n");
396
397 // ========================================================================
398 // Example 14: Custom types
399 // ========================================================================
400 println!("Example 14: Custom types");
401 println!("{}", "-".repeat(50));
402
403 #[derive(Debug, Clone)]
404 struct Point {
405 x: i32,
406 y: i32,
407 }
408
409 let analyzer = BoxConsumer::new(|p: &Point| {
410 println!("Point coordinates: ({}, {})", p.x, p.y);
411 })
412 .and_then(|p: &Point| {
413 let distance = ((p.x * p.x + p.y * p.y) as f64).sqrt();
414 println!("Distance from origin: {:.2}", distance);
415 })
416 .and_then(|p: &Point| {
417 let quadrant = match (p.x >= 0, p.y >= 0) {
418 (true, true) => "First quadrant",
419 (false, true) => "Second quadrant",
420 (false, false) => "Third quadrant",
421 (true, false) => "Fourth quadrant",
422 };
423 println!("Quadrant: {}", quadrant);
424 });
425
426 let point = Point { x: 3, y: 4 };
427 println!("Analyzing point: {:?}", point);
428 analyzer.accept(&point);
429 println!("Original point: {:?} (not modified)\n", point);
430
431 // ========================================================================
432 // Example 15: Data collection and statistics
433 // ========================================================================
434 println!("Example 15: Data collection and statistics");
435 println!("{}", "-".repeat(50));
436
437 let sum = Arc::new(Mutex::new(0));
438 let count = Arc::new(Mutex::new(0));
439 let sum_clone = sum.clone();
440 let count_clone = count.clone();
441
442 let collector = BoxConsumer::new(move |x: &i32| {
443 *sum_clone.lock().unwrap() += *x;
444 *count_clone.lock().unwrap() += 1;
445 });
446
447 let numbers = vec![10, 20, 30, 40, 50];
448 println!("Numbers: {:?}", numbers);
449 for num in &numbers {
450 collector.accept(num);
451 }
452
453 let total = *sum.lock().unwrap();
454 let cnt = *count.lock().unwrap();
455 println!("Sum: {}", total);
456 println!("Count: {}", cnt);
457 println!("Average: {:.2}\n", total as f64 / cnt as f64);
458
459 println!("=== All examples completed ===");
460 println!("\nTip: For value modification functionality, please refer to mutator_demo.rs");
461}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().unwrap().push(*x * 2);
66 })
67 .and_then(move |x: &i32| {
68 r2.lock().unwrap().push(*x + 10);
69 })
70 .and_then(move |x: &i32| {
71 r3.lock().unwrap().push(*x);
72 println!("Processing value: {}", x);
73 });
74
75 let value = 5;
76 println!("Initial value: {}", value);
77 chained.accept(&value);
78 println!("Collected results: {:?}", *results.lock().unwrap());
79 println!("Original value: {} (not modified)\n", value);
80
81 // ========================================================================
82 // Example 3: Closure extension methods
83 // ========================================================================
84 println!("Example 3: Direct use of extension methods on closures");
85 println!("{}", "-".repeat(50));
86
87 let result = Arc::new(Mutex::new(0));
88 let r1 = result.clone();
89 let r2 = result.clone();
90
91 let closure_chain = (move |x: &i32| {
92 *r1.lock().unwrap() = *x * 2;
93 })
94 .and_then(move |_x: &i32| {
95 *r2.lock().unwrap() += 10;
96 });
97
98 let value = 5;
99 println!("Initial value: {}", value);
100 closure_chain.accept(&value);
101 println!("Calculation result: {}", *result.lock().unwrap());
102 println!("Original value: {} (not modified)\n", value);
103
104 // ========================================================================
105 // Example 4: BoxConsumer factory methods
106 // ========================================================================
107 println!("Example 4: BoxConsumer factory methods");
108 println!("{}", "-".repeat(50));
109
110 // noop
111 println!("noop - does nothing:");
112 let noop = BoxConsumer::<i32>::noop();
113 let value = 42;
114 noop.accept(&value);
115 println!("Value: {}\n", value);
116
117 // print
118 print!("print - prints value: ");
119 let print = BoxConsumer::new(|x: &i32| println!("{}", x));
120 let value = 42;
121 print.accept(&value);
122 println!();
123
124 // print with prefix
125 let print_with = BoxConsumer::new(|x: &i32| println!("Value is: {}", x));
126 let value = 42;
127 print_with.accept(&value);
128 println!();
129
130 // ========================================================================
131 // Example 5: Conditional Consumer
132 // ========================================================================
133 println!("Example 5: Conditional Consumer");
134 println!("{}", "-".repeat(50));
135
136 // when
137 let mut check_positive =
138 BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x)).when(|x: &i32| *x > 0);
139
140 let positive = 5;
141 let negative = -5;
142 print!("Check {}: ", positive);
143 check_positive.accept(&positive);
144 print!("Check {}: ", negative);
145 check_positive.accept(&negative);
146 println!("(negative numbers not printed)\n");
147
148 // when().or_else()
149 let mut categorize = BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x))
150 .when(|x: &i32| *x > 0)
151 .or_else(|x: &i32| println!("Non-positive: {}", x));
152
153 let positive = 10;
154 let negative = -10;
155 categorize.accept(&positive);
156 categorize.accept(&negative);
157 println!();
158
159 // ========================================================================
160 // Example 6: ArcConsumer - multi-threaded sharing
161 // ========================================================================
162 println!("Example 6: ArcConsumer - multi-threaded sharing");
163 println!("{}", "-".repeat(50));
164
165 let shared = ArcConsumer::new(|x: &i32| println!("Processing value: {}", x * 2));
166
167 // Clone for another thread
168 let shared_clone = shared.clone();
169 let handle = thread::spawn(move || {
170 let value = 5;
171 let consumer = shared_clone;
172 consumer.accept(&value);
173 value
174 });
175
176 // Use in main thread
177 let value = 3;
178 let consumer = shared;
179 consumer.accept(&value);
180
181 let thread_result = handle.join().unwrap();
182 println!("Thread result: {}\n", thread_result);
183
184 // ========================================================================
185 // Example 7: ArcConsumer composition (does not consume original consumer)
186 // ========================================================================
187 println!("Example 7: ArcConsumer composition (borrowing &self)");
188 println!("{}", "-".repeat(50));
189
190 let double = ArcConsumer::new(|x: &i32| println!("double: {}", x * 2));
191 let add_ten = ArcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
192
193 // Composition does not consume original consumer
194 let pipeline1 = double.and_then(add_ten.clone());
195 let pipeline2 = add_ten.and_then(double.clone());
196
197 let value1 = 5;
198 let p1 = pipeline1;
199 print!("pipeline1 processing 5: ");
200 p1.accept(&value1);
201
202 let value2 = 5;
203 let p2 = pipeline2;
204 print!("pipeline2 processing 5: ");
205 p2.accept(&value2);
206
207 // double and add_ten are still available
208 let value3 = 10;
209 let d = double;
210 print!("Original double still available, processing 10: ");
211 d.accept(&value3);
212 println!();
213
214 // ========================================================================
215 // Example 8: RcConsumer - single-threaded sharing
216 // ========================================================================
217 println!("Example 8: RcConsumer - single-threaded sharing");
218 println!("{}", "-".repeat(50));
219
220 let rc_consumer = RcConsumer::new(|x: &i32| println!("Processing: {}", x * 2));
221
222 // Clone multiple copies
223 let clone1 = rc_consumer.clone();
224 let clone2 = rc_consumer.clone();
225
226 let value1 = 5;
227 let c1 = clone1;
228 print!("clone1 processing 5: ");
229 c1.accept(&value1);
230
231 let value2 = 3;
232 let c2 = clone2;
233 print!("clone2 processing 3: ");
234 c2.accept(&value2);
235
236 let value3 = 7;
237 let c3 = rc_consumer;
238 print!("Original processing 7: ");
239 c3.accept(&value3);
240 println!();
241
242 // ========================================================================
243 // Example 9: RcConsumer composition (borrowing &self)
244 // ========================================================================
245 println!("Example 9: RcConsumer composition (borrowing &self)");
246 println!("{}", "-".repeat(50));
247
248 let double = RcConsumer::new(|x: &i32| println!("double: {}", x * 2));
249 let add_ten = RcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
250
251 let pipeline1 = double.and_then(add_ten.clone());
252 let pipeline2 = add_ten.and_then(double.clone());
253
254 let value1 = 5;
255 let p1 = pipeline1;
256 print!("pipeline1 processing 5: ");
257 p1.accept(&value1);
258
259 let value2 = 5;
260 let p2 = pipeline2;
261 print!("pipeline2 processing 5: ");
262 p2.accept(&value2);
263 println!();
264
265 // ========================================================================
266 // Example 10: Unified Consumer trait
267 // ========================================================================
268 println!("Example 10: Unified Consumer trait");
269 println!("{}", "-".repeat(50));
270
271 fn log_all<C: Consumer<i32>>(consumer: &mut C, values: &[i32]) {
272 for value in values.iter() {
273 consumer.accept(value);
274 }
275 }
276
277 let values = vec![1, 2, 3, 4, 5];
278
279 let mut box_con = BoxConsumer::new(|x: &i32| print!("{} ", x * 2));
280 print!("BoxConsumer processing {:?}: ", values);
281 log_all(&mut box_con, &values);
282 println!();
283
284 let mut arc_con = ArcConsumer::new(|x: &i32| print!("{} ", x * 2));
285 print!("ArcConsumer processing {:?}: ", values);
286 log_all(&mut arc_con, &values);
287 println!();
288
289 let mut rc_con = RcConsumer::new(|x: &i32| print!("{} ", x * 2));
290 print!("RcConsumer processing {:?}: ", values);
291 log_all(&mut rc_con, &values);
292 println!();
293
294 let mut closure = |x: &i32| print!("{} ", x * 2);
295 print!("Closure processing {:?}: ", values);
296 log_all(&mut closure, &values);
297 println!("\n");
298
299 // ========================================================================
300 // Example 11: Data validation and logging
301 // ========================================================================
302 println!("Example 11: Data validation and logging");
303 println!("{}", "-".repeat(50));
304
305 let validator = BoxConsumer::new(|x: &i32| {
306 let status = if *x >= 0 && *x <= 100 {
307 "valid"
308 } else {
309 "out of range"
310 };
311 println!("Validate {}: {}", x, status);
312 });
313
314 let logger = BoxConsumer::new(|x: &i32| {
315 println!("Log to file: value={}, square={}", x, x * x);
316 });
317
318 let pipeline = validator.and_then(logger);
319
320 let test_values = vec![-50, 30, 200];
321 for value in test_values {
322 pipeline.accept(&value);
323 }
324 println!();
325
326 // ========================================================================
327 // Example 12: String analysis
328 // ========================================================================
329 println!("Example 12: String analysis");
330 println!("{}", "-".repeat(50));
331
332 let string_analyzer = BoxConsumer::new(|s: &String| {
333 println!("Length: {}", s.len());
334 })
335 .and_then(|s: &String| {
336 println!("Lowercase: {}", s.to_lowercase());
337 })
338 .and_then(|s: &String| {
339 println!("Uppercase: {}", s.to_uppercase());
340 })
341 .and_then(|s: &String| {
342 let word_count = s.split_whitespace().count();
343 println!("Word count: {}", word_count);
344 });
345
346 let text = String::from("Hello World");
347 println!("Analyzing text: \"{}\"", text);
348 string_analyzer.accept(&text);
349 println!("Original text: \"{}\" (not modified)\n", text);
350
351 // ========================================================================
352 // Example 13: Type conversion
353 // ========================================================================
354 println!("Example 13: Type conversion");
355 println!("{}", "-".repeat(50));
356
357 // Closure -> BoxConsumer
358 let closure = |x: &i32| print!("Processing: {} ", x * 2);
359 let box_con = Consumer::into_box(closure);
360 let value = 5;
361 print!("Closure -> BoxConsumer: ");
362 box_con.accept(&value);
363 println!();
364
365 // Closure -> RcConsumer
366 let closure = |x: &i32| print!("Processing: {} ", x * 2);
367 let rc_con = Consumer::into_rc(closure);
368 let value = 5;
369 print!("Closure -> RcConsumer: ");
370 rc_con.accept(&value);
371 println!();
372
373 // Closure -> ArcConsumer
374 let closure = |x: &i32| print!("Processing: {} ", x * 2);
375 let arc_con = Consumer::into_arc(closure);
376 let value = 5;
377 print!("Closure -> ArcConsumer: ");
378 arc_con.accept(&value);
379 println!();
380
381 // BoxConsumer -> RcConsumer
382 let box_con = BoxConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
383 let rc_con = box_con.into_rc();
384 let value = 5;
385 print!("BoxConsumer -> RcConsumer: ");
386 rc_con.accept(&value);
387 println!();
388
389 // RcConsumer -> BoxConsumer
390 let rc_con = RcConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
391 let box_con = rc_con.into_box();
392 let value = 5;
393 print!("RcConsumer -> BoxConsumer: ");
394 box_con.accept(&value);
395 println!("\n");
396
397 // ========================================================================
398 // Example 14: Custom types
399 // ========================================================================
400 println!("Example 14: Custom types");
401 println!("{}", "-".repeat(50));
402
403 #[derive(Debug, Clone)]
404 struct Point {
405 x: i32,
406 y: i32,
407 }
408
409 let analyzer = BoxConsumer::new(|p: &Point| {
410 println!("Point coordinates: ({}, {})", p.x, p.y);
411 })
412 .and_then(|p: &Point| {
413 let distance = ((p.x * p.x + p.y * p.y) as f64).sqrt();
414 println!("Distance from origin: {:.2}", distance);
415 })
416 .and_then(|p: &Point| {
417 let quadrant = match (p.x >= 0, p.y >= 0) {
418 (true, true) => "First quadrant",
419 (false, true) => "Second quadrant",
420 (false, false) => "Third quadrant",
421 (true, false) => "Fourth quadrant",
422 };
423 println!("Quadrant: {}", quadrant);
424 });
425
426 let point = Point { x: 3, y: 4 };
427 println!("Analyzing point: {:?}", point);
428 analyzer.accept(&point);
429 println!("Original point: {:?} (not modified)\n", point);
430
431 // ========================================================================
432 // Example 15: Data collection and statistics
433 // ========================================================================
434 println!("Example 15: Data collection and statistics");
435 println!("{}", "-".repeat(50));
436
437 let sum = Arc::new(Mutex::new(0));
438 let count = Arc::new(Mutex::new(0));
439 let sum_clone = sum.clone();
440 let count_clone = count.clone();
441
442 let collector = BoxConsumer::new(move |x: &i32| {
443 *sum_clone.lock().unwrap() += *x;
444 *count_clone.lock().unwrap() += 1;
445 });
446
447 let numbers = vec![10, 20, 30, 40, 50];
448 println!("Numbers: {:?}", numbers);
449 for num in &numbers {
450 collector.accept(num);
451 }
452
453 let total = *sum.lock().unwrap();
454 let cnt = *count.lock().unwrap();
455 println!("Sum: {}", total);
456 println!("Count: {}", cnt);
457 println!("Average: {:.2}\n", total as f64 / cnt as f64);
458
459 println!("=== All examples completed ===");
460 println!("\nTip: For value modification functionality, please refer to mutator_demo.rs");
461}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().unwrap().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!(" Result: {:?}\n", *log.lock().unwrap());
39
40 // Example 2: Using ArcConsumer::to_fn can be used multiple times
41 println!("2. ArcConsumer::to_fn can be used multiple times");
42 let log2 = Arc::new(Mutex::new(Vec::new()));
43 let l2 = log2.clone();
44 let consumer2 = ArcConsumer::new(move |x: &i32| {
45 l2.lock().unwrap().push(*x + 10);
46 });
47
48 // to_fn doesn't consume consumer, can be called multiple times
49 [1, 2, 3].iter().for_each(consumer2.to_fn());
50 println!(" First time: {:?}", *log2.lock().unwrap());
51
52 [4, 5].iter().for_each(consumer2.to_fn());
53 println!(" Second time: {:?}\n", *log2.lock().unwrap());
54
55 // Example 3: Using RcConsumer::to_fn
56 println!("3. RcConsumer::to_fn used for single-threaded scenarios");
57 let log3 = Rc::new(RefCell::new(Vec::new()));
58 let l3 = log3.clone();
59 let consumer3 = RcConsumer::new(move |x: &i32| {
60 l3.borrow_mut().push(*x * 3);
61 });
62
63 [1, 2, 3, 4].iter().for_each(consumer3.to_fn());
64 println!(" Result: {:?}\n", *log3.borrow());
65
66 // Example 4: Using in custom functions
67 println!("4. Using in custom functions");
68 fn process_items<F>(items: Vec<i32>, consumer: F)
69 where
70 F: FnMut(&i32),
71 {
72 items.iter().for_each(consumer);
73 }
74
75 let log4 = Arc::new(Mutex::new(Vec::new()));
76 let l4 = log4.clone();
77 let consumer4 = BoxConsumer::new(move |x: &i32| {
78 l4.lock().unwrap().push(*x * 5);
79 });
80
81 // Use into_fn to convert Consumer to closure and pass to function
82 process_items(vec![1, 2, 3], consumer4.into_fn());
83 println!(" Result: {:?}\n", *log4.lock().unwrap());
84
85 // Example 5: Using into_fn after chained operations
86 println!("5. Using into_fn after chained operations");
87 let log5 = Arc::new(Mutex::new(Vec::new()));
88 let l5 = log5.clone();
89 let l6 = log5.clone();
90
91 let chained = BoxConsumer::new(move |x: &i32| {
92 l5.lock().unwrap().push(format!("A: {}", x));
93 })
94 .and_then(move |x: &i32| {
95 l6.lock().unwrap().push(format!("B: {}", x));
96 });
97
98 [1, 2].iter().for_each(chained.into_fn());
99 println!(" Result: {:?}\n", *log5.lock().unwrap());
100
101 println!("=== Demo Complete ===");
102}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().unwrap().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!(" Result: {:?}\n", *log.lock().unwrap());
39
40 // Example 2: Using ArcConsumer::to_fn can be used multiple times
41 println!("2. ArcConsumer::to_fn can be used multiple times");
42 let log2 = Arc::new(Mutex::new(Vec::new()));
43 let l2 = log2.clone();
44 let consumer2 = ArcConsumer::new(move |x: &i32| {
45 l2.lock().unwrap().push(*x + 10);
46 });
47
48 // to_fn doesn't consume consumer, can be called multiple times
49 [1, 2, 3].iter().for_each(consumer2.to_fn());
50 println!(" First time: {:?}", *log2.lock().unwrap());
51
52 [4, 5].iter().for_each(consumer2.to_fn());
53 println!(" Second time: {:?}\n", *log2.lock().unwrap());
54
55 // Example 3: Using RcConsumer::to_fn
56 println!("3. RcConsumer::to_fn used for single-threaded scenarios");
57 let log3 = Rc::new(RefCell::new(Vec::new()));
58 let l3 = log3.clone();
59 let consumer3 = RcConsumer::new(move |x: &i32| {
60 l3.borrow_mut().push(*x * 3);
61 });
62
63 [1, 2, 3, 4].iter().for_each(consumer3.to_fn());
64 println!(" Result: {:?}\n", *log3.borrow());
65
66 // Example 4: Using in custom functions
67 println!("4. Using in custom functions");
68 fn process_items<F>(items: Vec<i32>, consumer: F)
69 where
70 F: FnMut(&i32),
71 {
72 items.iter().for_each(consumer);
73 }
74
75 let log4 = Arc::new(Mutex::new(Vec::new()));
76 let l4 = log4.clone();
77 let consumer4 = BoxConsumer::new(move |x: &i32| {
78 l4.lock().unwrap().push(*x * 5);
79 });
80
81 // Use into_fn to convert Consumer to closure and pass to function
82 process_items(vec![1, 2, 3], consumer4.into_fn());
83 println!(" Result: {:?}\n", *log4.lock().unwrap());
84
85 // Example 5: Using into_fn after chained operations
86 println!("5. Using into_fn after chained operations");
87 let log5 = Arc::new(Mutex::new(Vec::new()));
88 let l5 = log5.clone();
89 let l6 = log5.clone();
90
91 let chained = BoxConsumer::new(move |x: &i32| {
92 l5.lock().unwrap().push(format!("A: {}", x));
93 })
94 .and_then(move |x: &i32| {
95 l6.lock().unwrap().push(format!("B: {}", x));
96 });
97
98 [1, 2].iter().for_each(chained.into_fn());
99 println!(" Result: {:?}\n", *log5.lock().unwrap());
100
101 println!("=== Demo Complete ===");
102}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);