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