BoxConsumer

Struct BoxConsumer 

Source
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,

Source

pub fn new<F>(f: F) -> Self
where F: FnMut(&T) + 'static,

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?
examples/consumer_fn_usage.rs (lines 23-25)
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
Hide additional examples
examples/consumer_demo.rs (lines 33-35)
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}
Source

pub fn new_with_name<F>(name: impl Into<String>, f: F) -> Self
where F: FnMut(&T) + 'static,

Create a new named BoxConsumer

§Type Parameters
  • F - Closure type
§Parameters
  • name - Name of the consumer
  • 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_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]);
Source

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 unchanged
Examples found in repository?
examples/consumer_demo.rs (line 100)
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}
Source

pub fn name(&self) -> Option<&str>

Get the consumer’s name

§Return Value

Returns the consumer’s name, or None if not set

Source

pub fn set_name(&mut self, name: impl Into<String>)

Set the consumer’s name

§Parameters
  • name - Name to set
Source

pub fn and_then<C>(self, next: C) -> Self
where 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 implements Clone). Can be:
    • A closure: |x: &T|
    • A BoxConsumer<T>
    • An RcConsumer<T>
    • An ArcConsumer<T>
    • Any type implementing Consumer<T>
§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?
examples/consumer_fn_usage.rs (lines 85-87)
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
Hide additional examples
examples/consumer_demo.rs (lines 55-57)
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}
Source

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 implements Clone). 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>
§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?
examples/consumer_demo.rs (line 126)
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>

Source§

fn accept(&mut self, value: &T)

Execute consumption operation Read more
Source§

fn into_box(self) -> BoxConsumer<T>
where T: 'static,

Convert to BoxConsumer Read more
Source§

fn into_rc(self) -> RcConsumer<T>
where T: 'static,

Convert to RcConsumer Read more
Source§

fn into_fn(self) -> impl FnMut(&T)
where T: 'static,

Convert to closure Read more
Source§

fn into_arc(self) -> ArcConsumer<T>
where Self: Sized + Send + 'static, T: Send + 'static,

Convert to ArcConsumer Read more
Source§

impl<T> ConsumerOnce<T> for BoxConsumer<T>

Source§

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,

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,

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]);
Source§

impl<T> Debug for BoxConsumer<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Display for BoxConsumer<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for BoxConsumer<T>

§

impl<T> !RefUnwindSafe for BoxConsumer<T>

§

impl<T> !Send for BoxConsumer<T>

§

impl<T> !Sync for BoxConsumer<T>

§

impl<T> Unpin for BoxConsumer<T>

§

impl<T> !UnwindSafe for BoxConsumer<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.