pub struct ArcConsumer<T> { /* private fields */ }Expand description
ArcConsumer struct
Non-mutating consumer implementation based on Arc<dyn Fn(&T) + Send + Sync>,
for thread-safe shared ownership scenarios. The wrapper does not need
Mutex because it only invokes a shared Fn.
§Features
- Shared Ownership: Cloneable through
Arc, allows multiple owners - Thread Safe: Implements
Send + Sync, can be safely used concurrently - Lock-free Wrapper: No Mutex protection needed by the wrapper
- Non-consuming API:
and_thenborrows&self, original object remains usable
§Use Cases
Choose ArcConsumer when:
- Need to share non-mutating consumer across multiple threads
- Pure observation operations, such as logging, monitoring, notifications
- Need high-concurrency reads with no lock overhead
§Performance Advantages
Compared to ArcStatefulConsumer, ArcConsumer has no Mutex lock overhead,
performing better in high-concurrency observation scenarios.
§Examples
use qubit_function::{Consumer, ArcConsumer};
let consumer = ArcConsumer::new(|x: &i32| {
println!("Observed: {}", x);
});
let clone = consumer.clone();
consumer.accept(&5);
clone.accept(&10);Implementations§
Source§impl<T> ArcConsumer<T>
impl<T> ArcConsumer<T>
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new consumer.
Wraps the provided closure in the appropriate smart pointer type for this consumer implementation.
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}More examples
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}Sourcepub fn new_with_name<F>(name: &str, f: F) -> Self
pub fn new_with_name<F>(name: &str, f: F) -> Self
Creates a new named consumer.
Wraps the provided closure and assigns it a name, which is useful for debugging and logging purposes.
Sourcepub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
pub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
Creates a new named consumer with an optional name.
Wraps the provided closure and assigns it an optional name.
Sourcepub fn clear_name(&mut self)
pub fn clear_name(&mut self)
Clears the name of this consumer.
Sourcepub fn noop() -> Self
pub fn noop() -> Self
Creates a no-operation consumer.
Creates a consumer that does nothing when called. Useful for default values or placeholder implementations.
§Returns
Returns a new consumer instance that performs no operation.
Sourcepub fn when<P>(&self, predicate: P) -> ArcConditionalConsumer<T>
pub fn when<P>(&self, predicate: P) -> ArcConditionalConsumer<T>
Creates a conditional consumer
Wraps this consumer with a predicate condition, creating a new conditional consumer that will only execute the original consumer when the predicate evaluates to true.
§Parameters
predicate- The condition that must be satisfied for the consumer to execute
§Returns
Returns a conditional consumer that executes this consumer only when the predicate is satisfied
§Examples
use qubit_function::{ArcConsumer, Consumer};
let consumer = ArcConsumer::new(|x: &i32| println!("{}", x));
let conditional = consumer.when(|x: &i32| *x > 0);
conditional.accept(&5); // prints: 5
conditional.accept(&-5); // prints nothingSourcepub fn and_then<C>(&self, after: C) -> ArcConsumer<T>
pub fn and_then<C>(&self, after: C) -> ArcConsumer<T>
Chains another consumer in sequence
Combines this consumer with another consumer into a new consumer
that executes both consumers in sequence. The returned consumer
first executes this consumer, then unconditionally executes the
after consumer.
§Parameters
after- The consumer to execute after this one (always executed)
§Returns
Returns a new consumer that executes both consumers in sequence
§Examples
use qubit_function::{ArcConsumer, Consumer};
let consumer1 = ArcConsumer::new(|x: &i32| print!("first: {}", x));
let consumer2 = ArcConsumer::new(|x: &i32| println!(" second: {}", x));
let chained = consumer1.and_then(consumer2);
chained.accept(&5); // prints: first: 5 second: 5Examples 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}Trait Implementations§
Source§impl<T> Clone for ArcConsumer<T>
impl<T> Clone for ArcConsumer<T>
Source§impl<T> Consumer<T> for ArcConsumer<T>
impl<T> Consumer<T> for ArcConsumer<T>
Source§fn into_box(self) -> BoxConsumer<T>where
Self: 'static,
fn into_box(self) -> BoxConsumer<T>where
Self: 'static,
Source§fn into_rc(self) -> RcConsumer<T>where
Self: 'static,
fn into_rc(self) -> RcConsumer<T>where
Self: 'static,
Source§fn into_arc(self) -> ArcConsumer<T>
fn into_arc(self) -> ArcConsumer<T>
Source§fn into_once(self) -> BoxConsumerOnce<T>where
Self: 'static,
fn into_once(self) -> BoxConsumerOnce<T>where
Self: 'static,
Source§fn to_box(&self) -> BoxConsumer<T>where
Self: 'static,
fn to_box(&self) -> BoxConsumer<T>where
Self: 'static,
BoxConsumer Read moreSource§fn to_rc(&self) -> RcConsumer<T>where
Self: 'static,
fn to_rc(&self) -> RcConsumer<T>where
Self: 'static,
RcConsumer Read moreSource§fn to_arc(&self) -> ArcConsumer<T>
fn to_arc(&self) -> ArcConsumer<T>
ArcConsumer Read more