pub struct BoxConsumer<T> { /* private fields */ }Expand description
BoxConsumer struct
Consumer implementation based on Box<dyn FnMut(&T)> for single ownership
scenarios. When sharing is not needed, this is the simplest and most
efficient consumer type.
§Features
- Single Ownership: Not cloneable, transfers ownership when used
- Zero Overhead: No reference counting or lock overhead
- Mutable State: Can modify captured environment through
FnMut - Builder Pattern: Method chaining naturally consumes
self
§Use Cases
Choose BoxConsumer when:
- Consumer is used only once or in a linear flow
- Building pipelines where ownership flows naturally
- No need to share consumers across contexts
- Performance critical and cannot accept sharing overhead
§Performance
BoxConsumer has the best performance among the three consumer types:
- No reference counting overhead
- No lock acquisition or runtime borrowing checks
- Direct function calls through vtable
- Minimal memory footprint (single pointer)
§Examples
use prism3_function::{Consumer, BoxConsumer};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let mut consumer = BoxConsumer::new(move |x: &i32| {
l.lock().unwrap().push(*x);
});
consumer.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![5]);§Author
Hu Haixing
Implementations§
Source§impl<T> BoxConsumer<T>where
T: 'static,
impl<T> BoxConsumer<T>where
T: 'static,
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Create a new BoxConsumer
§Type Parameters
F- Closure type
§Parameters
f- Closure to wrap
§Return Value
Returns a new BoxConsumer<T> instance
§Examples
use prism3_function::{Consumer, BoxConsumer};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let mut consumer = BoxConsumer::new(move |x: &i32| {
l.lock().unwrap().push(*x + 1);
});
consumer.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![6]);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}More examples
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}Sourcepub fn new_with_name<F>(name: impl Into<String>, f: F) -> Self
pub fn new_with_name<F>(name: impl Into<String>, f: F) -> Self
Create a new named BoxConsumer
§Type Parameters
F- Closure type
§Parameters
name- Name of the consumerf- Closure to wrap
§Return Value
Returns a new BoxConsumer<T> instance
§Examples
use prism3_function::{Consumer, BoxConsumer};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let mut consumer = BoxConsumer::new_with_name("my_consumer", move |x: &i32| {
l.lock().unwrap().push(*x + 1);
});
assert_eq!(consumer.name(), Some("my_consumer"));
consumer.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![6]);Sourcepub fn noop() -> Self
pub fn noop() -> Self
Create a no-op consumer
Returns a consumer that performs no operation.
§Return Value
Returns a no-op consumer
§Examples
use prism3_function::{Consumer, BoxConsumer};
let mut noop = BoxConsumer::<i32>::noop();
noop.accept(&42);
// Value unchangedExamples 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}Sourcepub fn and_then<C>(self, next: C) -> Selfwhere
C: Consumer<T> + 'static,
pub fn and_then<C>(self, next: C) -> Selfwhere
C: Consumer<T> + 'static,
Sequentially chain another consumer
Returns a new consumer that executes the current operation first, then the next operation. Consumes self.
§Type Parameters
C- Type of the next consumer
§Parameters
next- Consumer to execute after the current operation. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original consumer, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| - A
BoxConsumer<T> - An
RcConsumer<T> - An
ArcConsumer<T> - Any type implementing
Consumer<T>
- A closure:
§Return Value
Returns a new combined BoxConsumer<T>
§Examples
§Direct value passing (ownership transfer)
use prism3_function::{Consumer, BoxConsumer};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l1 = log.clone();
let l2 = log.clone();
let first = BoxConsumer::new(move |x: &i32| {
l1.lock().unwrap().push(*x * 2);
});
let second = BoxConsumer::new(move |x: &i32| {
l2.lock().unwrap().push(*x + 10);
});
// second is moved here
let mut chained = first.and_then(second);
chained.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![10, 15]);
// second.accept(&3); // Would not compile - moved§Preserving original with clone
use prism3_function::{Consumer, BoxConsumer};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l1 = log.clone();
let l2 = log.clone();
let first = BoxConsumer::new(move |x: &i32| {
l1.lock().unwrap().push(*x * 2);
});
let second = BoxConsumer::new(move |x: &i32| {
l2.lock().unwrap().push(*x + 10);
});
// Clone to preserve original
let mut chained = first.and_then(second.clone());
chained.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![10, 15]);
// Original still usable
second.accept(&3);
assert_eq!(*log.lock().unwrap(), vec![10, 15, 13]);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}More examples
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}Sourcepub fn when<P>(self, predicate: P) -> BoxConditionalConsumer<T>where
P: Predicate<T> + 'static,
pub fn when<P>(self, predicate: P) -> BoxConditionalConsumer<T>where
P: Predicate<T> + 'static,
Creates a conditional consumer
Returns a consumer that only executes when a predicate is satisfied.
§Parameters
predicate- The condition to check. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Return Value
Returns BoxConditionalConsumer<T>
§Examples
§Using a closure
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 conditional = consumer.when(|x: &i32| *x > 0);
conditional.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![5]);
conditional.accept(&-5);
assert_eq!(*log.lock().unwrap(), vec![5]); // Unchanged§Preserving predicate with clone
use prism3_function::{Consumer, BoxConsumer};
use prism3_function::predicate::{Predicate, RcPredicate};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let consumer = BoxConsumer::new(move |x: &i32| {
l.lock().unwrap().push(*x);
});
// Clone to preserve original predicate
let mut conditional = consumer.when(is_positive.clone());
conditional.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![5]);
// Original predicate still usable
assert!(is_positive.test(&3));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}Trait Implementations§
Source§impl<T> Consumer<T> for BoxConsumer<T>
impl<T> Consumer<T> for BoxConsumer<T>
Source§fn into_box(self) -> BoxConsumer<T>where
T: 'static,
fn into_box(self) -> BoxConsumer<T>where
T: 'static,
Source§fn into_rc(self) -> RcConsumer<T>where
T: 'static,
fn into_rc(self) -> RcConsumer<T>where
T: 'static,
Source§impl<T> ConsumerOnce<T> for BoxConsumer<T>
impl<T> ConsumerOnce<T> for BoxConsumer<T>
Source§fn accept_once(self, value: &T)
fn accept_once(self, value: &T)
Execute one-time consumption operation
Executes the consumer operation once and consumes self. This method provides a bridge between the reusable Consumer interface and the one-time ConsumerOnce interface.
§Parameters
value- Reference to the value to be consumed
§Examples
use prism3_function::{Consumer, ConsumerOnce, 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);
});
consumer.accept_once(&5);
assert_eq!(*log.lock().unwrap(), vec![5]);Source§fn into_box_once(self) -> BoxConsumerOnce<T>where
T: 'static,
fn into_box_once(self) -> BoxConsumerOnce<T>where
T: 'static,
Convert to BoxConsumerOnce
⚠️ Consumes self: The original consumer will be unavailable after
calling this method.
Converts the current consumer to BoxConsumerOnce<T> by wrapping the
consumer’s accept method in a FnOnce closure.
§Return Value
Returns the wrapped BoxConsumerOnce<T>
§Examples
use prism3_function::{Consumer, ConsumerOnce, 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 box_consumer_once = consumer.into_box_once();
box_consumer_once.accept_once(&5);
assert_eq!(*log.lock().unwrap(), vec![5]);Source§fn into_fn_once(self) -> impl FnOnce(&T)where
T: 'static,
fn into_fn_once(self) -> impl FnOnce(&T)where
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 places
where the standard library requires FnOnce.
§Return Value
Returns a closure implementing FnOnce(&T)
§Examples
use prism3_function::{Consumer, ConsumerOnce, 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 func = consumer.into_fn_once();
func(&5);
assert_eq!(*log.lock().unwrap(), vec![5]);