pub struct BoxBiConsumerOnce<T, U> { /* private fields */ }Expand description
BoxBiConsumerOnce struct
A one-time bi-consumer implementation based on
Box<dyn FnOnce(&T, &U)> for single ownership scenarios. This is the
simplest one-time bi-consumer type for truly one-time use.
§Features
- Single Ownership: Not cloneable, ownership moves on use
- Zero Overhead: No reference counting or locking
- One-Time Use: Consumes self on first call
- Builder Pattern: Method chaining consumes
selfnaturally
§Use Cases
Choose BoxBiConsumerOnce when:
- The bi-consumer is truly used only once
- Building pipelines where ownership naturally flows
- The consumer captures values that should be consumed
- Performance is critical and sharing overhead is unacceptable
§Performance
BoxBiConsumerOnce has the best performance:
- No reference counting overhead
- No lock acquisition or runtime borrow checking
- Direct function call through vtable
- Minimal memory footprint (single pointer)
§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
let consumer = BoxBiConsumerOnce::new(|x: &i32, y: &i32| {
println!("Sum: {}", x + y);
});
consumer.accept_once(&5, &3);§Author
Haixing Hu
Implementations§
Source§impl<T, U> BoxBiConsumerOnce<T, U>where
T: 'static,
U: 'static,
impl<T, U> BoxBiConsumerOnce<T, U>where
T: 'static,
U: 'static,
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new BoxBiConsumerOnce
§Type Parameters
F- The closure type
§Parameters
f- The closure to wrap
§Returns
Returns a new BoxBiConsumerOnce<T, U> instance
§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
l.lock().unwrap().push(*x * 2 + *y);
});
consumer.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![13]);Examples found in repository?
18fn main() {
19 println!("=== BiConsumerOnce Demo ===\n");
20
21 // 1. Basic usage
22 println!("1. Basic usage:");
23 let log = Arc::new(Mutex::new(Vec::new()));
24 let l = log.clone();
25 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26 l.lock().unwrap().push(*x + *y);
27 println!(" Sum: {}", x + y);
28 });
29 consumer.accept_once(&10, &5);
30 println!(" Log: {:?}\n", *log.lock().unwrap());
31
32 // 2. Method chaining
33 println!("2. Method chaining:");
34 let log = Arc::new(Mutex::new(Vec::new()));
35 let l1 = log.clone();
36 let l2 = log.clone();
37 let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38 l1.lock().unwrap().push(*x + *y);
39 println!(" First: sum={}", x + y);
40 })
41 .and_then(move |x: &i32, y: &i32| {
42 l2.lock().unwrap().push(*x * *y);
43 println!(" Second: product={}", x * y);
44 });
45 chained.accept_once(&5, &3);
46 println!(" Log: {:?}\n", *log.lock().unwrap());
47
48 // 3. Conditional execution - true case
49 println!("3. Conditional execution - true case:");
50 let log = Arc::new(Mutex::new(Vec::new()));
51 let l = log.clone();
52 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53 l.lock().unwrap().push(*x + *y);
54 })
55 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56 conditional.accept_once(&5, &3);
57 println!(" Positive values: {:?}\n", *log.lock().unwrap());
58
59 // 4. Conditional execution - false case
60 println!("4. Conditional execution - false case:");
61 let log = Arc::new(Mutex::new(Vec::new()));
62 let l = log.clone();
63 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64 l.lock().unwrap().push(*x + *y);
65 })
66 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67 conditional.accept_once(&-5, &3);
68 println!(" Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70 // 5. Conditional branching
71 println!("5. Conditional branching:");
72 let log = Arc::new(Mutex::new(Vec::new()));
73 let l1 = log.clone();
74 let l2 = log.clone();
75 let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76 l1.lock().unwrap().push(*x);
77 })
78 .when(|x: &i32, y: &i32| *x > *y)
79 .or_else(move |_x: &i32, y: &i32| {
80 l2.lock().unwrap().push(*y);
81 });
82 branch.accept_once(&15, &10);
83 println!(" When x > y: {:?}\n", *log.lock().unwrap());
84
85 // 6. Working with closures directly
86 println!("6. Working with closures directly:");
87 let log = Arc::new(Mutex::new(Vec::new()));
88 let l = log.clone();
89 let closure = move |x: &i32, y: &i32| {
90 l.lock().unwrap().push(*x + *y);
91 println!(" Processed: {}", x + y);
92 };
93 closure.accept_once(&10, &20);
94 println!(" Log: {:?}\n", *log.lock().unwrap());
95
96 // 7. Moving captured values
97 println!("7. Moving captured values:");
98 let data = vec![1, 2, 3, 4, 5];
99 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100 println!(" x={}, y={}", x, y);
101 println!(" Captured data: {:?}", data);
102 println!(" Data sum: {}", data.iter().sum::<i32>());
103 });
104 consumer.accept_once(&5, &3);
105 // data is no longer available here
106 println!();
107
108 // 8. Initialization callback
109 println!("8. Initialization callback:");
110 let log = Arc::new(Mutex::new(Vec::new()));
111 let l = log.clone();
112 let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113 println!(" Initializing with dimensions: {}x{}", width, height);
114 l.lock().unwrap().push(*width * *height);
115 });
116 init_callback.accept_once(&800, &600);
117 println!(" Areas: {:?}\n", *log.lock().unwrap());
118
119 // 9. Cleanup callback
120 println!("9. Cleanup callback:");
121 let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122 println!(" Cleanup: processed {} out of {} items", count, total);
123 println!(
124 " Success rate: {:.1}%",
125 (*count as f64 / *total as f64) * 100.0
126 );
127 });
128 cleanup.accept_once(&85, &100);
129 println!();
130
131 // 10. Name support
132 println!("10. Name support:");
133 let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134 println!(" Initial name: {:?}", named_consumer.name());
135
136 named_consumer.set_name("init_callback");
137 println!(" After setting name: {:?}", named_consumer.name());
138 println!(" Display: {}", named_consumer);
139 named_consumer.accept_once(&1, &2);
140 println!();
141
142 // 11. Print helpers
143 println!("11. Print helpers:");
144 let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145 print.accept_once(&42, &10);
146
147 let print_with =
148 BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149 print_with.accept_once(&800, &600);
150 println!();
151
152 // 12. Converting to function
153 println!("12. Converting to function:");
154 let log = Arc::new(Mutex::new(Vec::new()));
155 let l = log.clone();
156 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157 l.lock().unwrap().push(*x + *y);
158 });
159 let func = consumer.into_fn_once();
160 func(&7, &3);
161 println!(" Log: {:?}\n", *log.lock().unwrap());
162
163 println!("=== Demo Complete ===");
164}Sourcepub fn new_with_name<F>(name: &str, f: F) -> Self
pub fn new_with_name<F>(name: &str, f: F) -> Self
Creates a new BoxBiConsumerOnce with a name
§Type Parameters
F- The closure type
§Parameters
name- The name of the consumerf- The closure to wrap
§Returns
Returns a new BoxBiConsumerOnce<T, U> instance with the specified name
§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let consumer = BoxBiConsumerOnce::new_with_name("sum_logger", move |x: &i32, y: &i32| {
l.lock().unwrap().push(*x + *y);
});
assert_eq!(consumer.name(), Some("sum_logger"));
consumer.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);Sourcepub fn name(&self) -> Option<&str>
pub fn name(&self) -> Option<&str>
Gets the name of the consumer
Examples found in repository?
18fn main() {
19 println!("=== BiConsumerOnce Demo ===\n");
20
21 // 1. Basic usage
22 println!("1. Basic usage:");
23 let log = Arc::new(Mutex::new(Vec::new()));
24 let l = log.clone();
25 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26 l.lock().unwrap().push(*x + *y);
27 println!(" Sum: {}", x + y);
28 });
29 consumer.accept_once(&10, &5);
30 println!(" Log: {:?}\n", *log.lock().unwrap());
31
32 // 2. Method chaining
33 println!("2. Method chaining:");
34 let log = Arc::new(Mutex::new(Vec::new()));
35 let l1 = log.clone();
36 let l2 = log.clone();
37 let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38 l1.lock().unwrap().push(*x + *y);
39 println!(" First: sum={}", x + y);
40 })
41 .and_then(move |x: &i32, y: &i32| {
42 l2.lock().unwrap().push(*x * *y);
43 println!(" Second: product={}", x * y);
44 });
45 chained.accept_once(&5, &3);
46 println!(" Log: {:?}\n", *log.lock().unwrap());
47
48 // 3. Conditional execution - true case
49 println!("3. Conditional execution - true case:");
50 let log = Arc::new(Mutex::new(Vec::new()));
51 let l = log.clone();
52 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53 l.lock().unwrap().push(*x + *y);
54 })
55 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56 conditional.accept_once(&5, &3);
57 println!(" Positive values: {:?}\n", *log.lock().unwrap());
58
59 // 4. Conditional execution - false case
60 println!("4. Conditional execution - false case:");
61 let log = Arc::new(Mutex::new(Vec::new()));
62 let l = log.clone();
63 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64 l.lock().unwrap().push(*x + *y);
65 })
66 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67 conditional.accept_once(&-5, &3);
68 println!(" Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70 // 5. Conditional branching
71 println!("5. Conditional branching:");
72 let log = Arc::new(Mutex::new(Vec::new()));
73 let l1 = log.clone();
74 let l2 = log.clone();
75 let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76 l1.lock().unwrap().push(*x);
77 })
78 .when(|x: &i32, y: &i32| *x > *y)
79 .or_else(move |_x: &i32, y: &i32| {
80 l2.lock().unwrap().push(*y);
81 });
82 branch.accept_once(&15, &10);
83 println!(" When x > y: {:?}\n", *log.lock().unwrap());
84
85 // 6. Working with closures directly
86 println!("6. Working with closures directly:");
87 let log = Arc::new(Mutex::new(Vec::new()));
88 let l = log.clone();
89 let closure = move |x: &i32, y: &i32| {
90 l.lock().unwrap().push(*x + *y);
91 println!(" Processed: {}", x + y);
92 };
93 closure.accept_once(&10, &20);
94 println!(" Log: {:?}\n", *log.lock().unwrap());
95
96 // 7. Moving captured values
97 println!("7. Moving captured values:");
98 let data = vec![1, 2, 3, 4, 5];
99 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100 println!(" x={}, y={}", x, y);
101 println!(" Captured data: {:?}", data);
102 println!(" Data sum: {}", data.iter().sum::<i32>());
103 });
104 consumer.accept_once(&5, &3);
105 // data is no longer available here
106 println!();
107
108 // 8. Initialization callback
109 println!("8. Initialization callback:");
110 let log = Arc::new(Mutex::new(Vec::new()));
111 let l = log.clone();
112 let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113 println!(" Initializing with dimensions: {}x{}", width, height);
114 l.lock().unwrap().push(*width * *height);
115 });
116 init_callback.accept_once(&800, &600);
117 println!(" Areas: {:?}\n", *log.lock().unwrap());
118
119 // 9. Cleanup callback
120 println!("9. Cleanup callback:");
121 let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122 println!(" Cleanup: processed {} out of {} items", count, total);
123 println!(
124 " Success rate: {:.1}%",
125 (*count as f64 / *total as f64) * 100.0
126 );
127 });
128 cleanup.accept_once(&85, &100);
129 println!();
130
131 // 10. Name support
132 println!("10. Name support:");
133 let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134 println!(" Initial name: {:?}", named_consumer.name());
135
136 named_consumer.set_name("init_callback");
137 println!(" After setting name: {:?}", named_consumer.name());
138 println!(" Display: {}", named_consumer);
139 named_consumer.accept_once(&1, &2);
140 println!();
141
142 // 11. Print helpers
143 println!("11. Print helpers:");
144 let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145 print.accept_once(&42, &10);
146
147 let print_with =
148 BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149 print_with.accept_once(&800, &600);
150 println!();
151
152 // 12. Converting to function
153 println!("12. Converting to function:");
154 let log = Arc::new(Mutex::new(Vec::new()));
155 let l = log.clone();
156 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157 l.lock().unwrap().push(*x + *y);
158 });
159 let func = consumer.into_fn_once();
160 func(&7, &3);
161 println!(" Log: {:?}\n", *log.lock().unwrap());
162
163 println!("=== Demo Complete ===");
164}Sourcepub fn set_name(&mut self, name: impl Into<String>)
pub fn set_name(&mut self, name: impl Into<String>)
Sets the name of the consumer
Examples found in repository?
18fn main() {
19 println!("=== BiConsumerOnce Demo ===\n");
20
21 // 1. Basic usage
22 println!("1. Basic usage:");
23 let log = Arc::new(Mutex::new(Vec::new()));
24 let l = log.clone();
25 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26 l.lock().unwrap().push(*x + *y);
27 println!(" Sum: {}", x + y);
28 });
29 consumer.accept_once(&10, &5);
30 println!(" Log: {:?}\n", *log.lock().unwrap());
31
32 // 2. Method chaining
33 println!("2. Method chaining:");
34 let log = Arc::new(Mutex::new(Vec::new()));
35 let l1 = log.clone();
36 let l2 = log.clone();
37 let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38 l1.lock().unwrap().push(*x + *y);
39 println!(" First: sum={}", x + y);
40 })
41 .and_then(move |x: &i32, y: &i32| {
42 l2.lock().unwrap().push(*x * *y);
43 println!(" Second: product={}", x * y);
44 });
45 chained.accept_once(&5, &3);
46 println!(" Log: {:?}\n", *log.lock().unwrap());
47
48 // 3. Conditional execution - true case
49 println!("3. Conditional execution - true case:");
50 let log = Arc::new(Mutex::new(Vec::new()));
51 let l = log.clone();
52 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53 l.lock().unwrap().push(*x + *y);
54 })
55 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56 conditional.accept_once(&5, &3);
57 println!(" Positive values: {:?}\n", *log.lock().unwrap());
58
59 // 4. Conditional execution - false case
60 println!("4. Conditional execution - false case:");
61 let log = Arc::new(Mutex::new(Vec::new()));
62 let l = log.clone();
63 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64 l.lock().unwrap().push(*x + *y);
65 })
66 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67 conditional.accept_once(&-5, &3);
68 println!(" Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70 // 5. Conditional branching
71 println!("5. Conditional branching:");
72 let log = Arc::new(Mutex::new(Vec::new()));
73 let l1 = log.clone();
74 let l2 = log.clone();
75 let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76 l1.lock().unwrap().push(*x);
77 })
78 .when(|x: &i32, y: &i32| *x > *y)
79 .or_else(move |_x: &i32, y: &i32| {
80 l2.lock().unwrap().push(*y);
81 });
82 branch.accept_once(&15, &10);
83 println!(" When x > y: {:?}\n", *log.lock().unwrap());
84
85 // 6. Working with closures directly
86 println!("6. Working with closures directly:");
87 let log = Arc::new(Mutex::new(Vec::new()));
88 let l = log.clone();
89 let closure = move |x: &i32, y: &i32| {
90 l.lock().unwrap().push(*x + *y);
91 println!(" Processed: {}", x + y);
92 };
93 closure.accept_once(&10, &20);
94 println!(" Log: {:?}\n", *log.lock().unwrap());
95
96 // 7. Moving captured values
97 println!("7. Moving captured values:");
98 let data = vec![1, 2, 3, 4, 5];
99 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100 println!(" x={}, y={}", x, y);
101 println!(" Captured data: {:?}", data);
102 println!(" Data sum: {}", data.iter().sum::<i32>());
103 });
104 consumer.accept_once(&5, &3);
105 // data is no longer available here
106 println!();
107
108 // 8. Initialization callback
109 println!("8. Initialization callback:");
110 let log = Arc::new(Mutex::new(Vec::new()));
111 let l = log.clone();
112 let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113 println!(" Initializing with dimensions: {}x{}", width, height);
114 l.lock().unwrap().push(*width * *height);
115 });
116 init_callback.accept_once(&800, &600);
117 println!(" Areas: {:?}\n", *log.lock().unwrap());
118
119 // 9. Cleanup callback
120 println!("9. Cleanup callback:");
121 let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122 println!(" Cleanup: processed {} out of {} items", count, total);
123 println!(
124 " Success rate: {:.1}%",
125 (*count as f64 / *total as f64) * 100.0
126 );
127 });
128 cleanup.accept_once(&85, &100);
129 println!();
130
131 // 10. Name support
132 println!("10. Name support:");
133 let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134 println!(" Initial name: {:?}", named_consumer.name());
135
136 named_consumer.set_name("init_callback");
137 println!(" After setting name: {:?}", named_consumer.name());
138 println!(" Display: {}", named_consumer);
139 named_consumer.accept_once(&1, &2);
140 println!();
141
142 // 11. Print helpers
143 println!("11. Print helpers:");
144 let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145 print.accept_once(&42, &10);
146
147 let print_with =
148 BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149 print_with.accept_once(&800, &600);
150 println!();
151
152 // 12. Converting to function
153 println!("12. Converting to function:");
154 let log = Arc::new(Mutex::new(Vec::new()));
155 let l = log.clone();
156 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157 l.lock().unwrap().push(*x + *y);
158 });
159 let func = consumer.into_fn_once();
160 func(&7, &3);
161 println!(" Log: {:?}\n", *log.lock().unwrap());
162
163 println!("=== Demo Complete ===");
164}Sourcepub fn noop() -> Self
pub fn noop() -> Self
Creates a no-op bi-consumer
§Returns
Returns a no-op bi-consumer
§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
let noop = BoxBiConsumerOnce::<i32, i32>::noop();
noop.accept_once(&42, &10);
// Values unchangedExamples found in repository?
18fn main() {
19 println!("=== BiConsumerOnce Demo ===\n");
20
21 // 1. Basic usage
22 println!("1. Basic usage:");
23 let log = Arc::new(Mutex::new(Vec::new()));
24 let l = log.clone();
25 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26 l.lock().unwrap().push(*x + *y);
27 println!(" Sum: {}", x + y);
28 });
29 consumer.accept_once(&10, &5);
30 println!(" Log: {:?}\n", *log.lock().unwrap());
31
32 // 2. Method chaining
33 println!("2. Method chaining:");
34 let log = Arc::new(Mutex::new(Vec::new()));
35 let l1 = log.clone();
36 let l2 = log.clone();
37 let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38 l1.lock().unwrap().push(*x + *y);
39 println!(" First: sum={}", x + y);
40 })
41 .and_then(move |x: &i32, y: &i32| {
42 l2.lock().unwrap().push(*x * *y);
43 println!(" Second: product={}", x * y);
44 });
45 chained.accept_once(&5, &3);
46 println!(" Log: {:?}\n", *log.lock().unwrap());
47
48 // 3. Conditional execution - true case
49 println!("3. Conditional execution - true case:");
50 let log = Arc::new(Mutex::new(Vec::new()));
51 let l = log.clone();
52 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53 l.lock().unwrap().push(*x + *y);
54 })
55 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56 conditional.accept_once(&5, &3);
57 println!(" Positive values: {:?}\n", *log.lock().unwrap());
58
59 // 4. Conditional execution - false case
60 println!("4. Conditional execution - false case:");
61 let log = Arc::new(Mutex::new(Vec::new()));
62 let l = log.clone();
63 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64 l.lock().unwrap().push(*x + *y);
65 })
66 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67 conditional.accept_once(&-5, &3);
68 println!(" Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70 // 5. Conditional branching
71 println!("5. Conditional branching:");
72 let log = Arc::new(Mutex::new(Vec::new()));
73 let l1 = log.clone();
74 let l2 = log.clone();
75 let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76 l1.lock().unwrap().push(*x);
77 })
78 .when(|x: &i32, y: &i32| *x > *y)
79 .or_else(move |_x: &i32, y: &i32| {
80 l2.lock().unwrap().push(*y);
81 });
82 branch.accept_once(&15, &10);
83 println!(" When x > y: {:?}\n", *log.lock().unwrap());
84
85 // 6. Working with closures directly
86 println!("6. Working with closures directly:");
87 let log = Arc::new(Mutex::new(Vec::new()));
88 let l = log.clone();
89 let closure = move |x: &i32, y: &i32| {
90 l.lock().unwrap().push(*x + *y);
91 println!(" Processed: {}", x + y);
92 };
93 closure.accept_once(&10, &20);
94 println!(" Log: {:?}\n", *log.lock().unwrap());
95
96 // 7. Moving captured values
97 println!("7. Moving captured values:");
98 let data = vec![1, 2, 3, 4, 5];
99 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100 println!(" x={}, y={}", x, y);
101 println!(" Captured data: {:?}", data);
102 println!(" Data sum: {}", data.iter().sum::<i32>());
103 });
104 consumer.accept_once(&5, &3);
105 // data is no longer available here
106 println!();
107
108 // 8. Initialization callback
109 println!("8. Initialization callback:");
110 let log = Arc::new(Mutex::new(Vec::new()));
111 let l = log.clone();
112 let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113 println!(" Initializing with dimensions: {}x{}", width, height);
114 l.lock().unwrap().push(*width * *height);
115 });
116 init_callback.accept_once(&800, &600);
117 println!(" Areas: {:?}\n", *log.lock().unwrap());
118
119 // 9. Cleanup callback
120 println!("9. Cleanup callback:");
121 let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122 println!(" Cleanup: processed {} out of {} items", count, total);
123 println!(
124 " Success rate: {:.1}%",
125 (*count as f64 / *total as f64) * 100.0
126 );
127 });
128 cleanup.accept_once(&85, &100);
129 println!();
130
131 // 10. Name support
132 println!("10. Name support:");
133 let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134 println!(" Initial name: {:?}", named_consumer.name());
135
136 named_consumer.set_name("init_callback");
137 println!(" After setting name: {:?}", named_consumer.name());
138 println!(" Display: {}", named_consumer);
139 named_consumer.accept_once(&1, &2);
140 println!();
141
142 // 11. Print helpers
143 println!("11. Print helpers:");
144 let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145 print.accept_once(&42, &10);
146
147 let print_with =
148 BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149 print_with.accept_once(&800, &600);
150 println!();
151
152 // 12. Converting to function
153 println!("12. Converting to function:");
154 let log = Arc::new(Mutex::new(Vec::new()));
155 let l = log.clone();
156 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157 l.lock().unwrap().push(*x + *y);
158 });
159 let func = consumer.into_fn_once();
160 func(&7, &3);
161 println!(" Log: {:?}\n", *log.lock().unwrap());
162
163 println!("=== Demo Complete ===");
164}Sourcepub fn and_then<C>(self, next: C) -> Selfwhere
C: BiConsumerOnce<T, U> + 'static,
pub fn and_then<C>(self, next: C) -> Selfwhere
C: BiConsumerOnce<T, U> + 'static,
Chains another one-time bi-consumer in sequence
Returns a new consumer executing the current operation first, then the next operation. Consumes self.
§Type Parameters
C- The type of the next consumer
§Parameters
next- The consumer to execute after the current operation. Note: This parameter is passed by value and will transfer ownership. SinceBoxBiConsumerOncecannot be cloned, the parameter will be consumed. Can be:- A closure:
|x: &T, y: &U| - A
BoxBiConsumerOnce<T, U> - Any type implementing
BiConsumerOnce<T, U>
- A closure:
§Returns
Returns a new composed BoxBiConsumerOnce<T, U>
§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l1 = log.clone();
let l2 = log.clone();
let first = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
l1.lock().unwrap().push(*x + *y);
});
let second = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
l2.lock().unwrap().push(*x * *y);
});
// Both first and second are moved and consumed
let chained = first.and_then(second);
chained.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8, 15]);
// first.accept(&2, &3); // Would not compile - moved
// second.accept(&2, &3); // Would not compile - movedExamples found in repository?
18fn main() {
19 println!("=== BiConsumerOnce Demo ===\n");
20
21 // 1. Basic usage
22 println!("1. Basic usage:");
23 let log = Arc::new(Mutex::new(Vec::new()));
24 let l = log.clone();
25 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26 l.lock().unwrap().push(*x + *y);
27 println!(" Sum: {}", x + y);
28 });
29 consumer.accept_once(&10, &5);
30 println!(" Log: {:?}\n", *log.lock().unwrap());
31
32 // 2. Method chaining
33 println!("2. Method chaining:");
34 let log = Arc::new(Mutex::new(Vec::new()));
35 let l1 = log.clone();
36 let l2 = log.clone();
37 let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38 l1.lock().unwrap().push(*x + *y);
39 println!(" First: sum={}", x + y);
40 })
41 .and_then(move |x: &i32, y: &i32| {
42 l2.lock().unwrap().push(*x * *y);
43 println!(" Second: product={}", x * y);
44 });
45 chained.accept_once(&5, &3);
46 println!(" Log: {:?}\n", *log.lock().unwrap());
47
48 // 3. Conditional execution - true case
49 println!("3. Conditional execution - true case:");
50 let log = Arc::new(Mutex::new(Vec::new()));
51 let l = log.clone();
52 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53 l.lock().unwrap().push(*x + *y);
54 })
55 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56 conditional.accept_once(&5, &3);
57 println!(" Positive values: {:?}\n", *log.lock().unwrap());
58
59 // 4. Conditional execution - false case
60 println!("4. Conditional execution - false case:");
61 let log = Arc::new(Mutex::new(Vec::new()));
62 let l = log.clone();
63 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64 l.lock().unwrap().push(*x + *y);
65 })
66 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67 conditional.accept_once(&-5, &3);
68 println!(" Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70 // 5. Conditional branching
71 println!("5. Conditional branching:");
72 let log = Arc::new(Mutex::new(Vec::new()));
73 let l1 = log.clone();
74 let l2 = log.clone();
75 let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76 l1.lock().unwrap().push(*x);
77 })
78 .when(|x: &i32, y: &i32| *x > *y)
79 .or_else(move |_x: &i32, y: &i32| {
80 l2.lock().unwrap().push(*y);
81 });
82 branch.accept_once(&15, &10);
83 println!(" When x > y: {:?}\n", *log.lock().unwrap());
84
85 // 6. Working with closures directly
86 println!("6. Working with closures directly:");
87 let log = Arc::new(Mutex::new(Vec::new()));
88 let l = log.clone();
89 let closure = move |x: &i32, y: &i32| {
90 l.lock().unwrap().push(*x + *y);
91 println!(" Processed: {}", x + y);
92 };
93 closure.accept_once(&10, &20);
94 println!(" Log: {:?}\n", *log.lock().unwrap());
95
96 // 7. Moving captured values
97 println!("7. Moving captured values:");
98 let data = vec![1, 2, 3, 4, 5];
99 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100 println!(" x={}, y={}", x, y);
101 println!(" Captured data: {:?}", data);
102 println!(" Data sum: {}", data.iter().sum::<i32>());
103 });
104 consumer.accept_once(&5, &3);
105 // data is no longer available here
106 println!();
107
108 // 8. Initialization callback
109 println!("8. Initialization callback:");
110 let log = Arc::new(Mutex::new(Vec::new()));
111 let l = log.clone();
112 let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113 println!(" Initializing with dimensions: {}x{}", width, height);
114 l.lock().unwrap().push(*width * *height);
115 });
116 init_callback.accept_once(&800, &600);
117 println!(" Areas: {:?}\n", *log.lock().unwrap());
118
119 // 9. Cleanup callback
120 println!("9. Cleanup callback:");
121 let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122 println!(" Cleanup: processed {} out of {} items", count, total);
123 println!(
124 " Success rate: {:.1}%",
125 (*count as f64 / *total as f64) * 100.0
126 );
127 });
128 cleanup.accept_once(&85, &100);
129 println!();
130
131 // 10. Name support
132 println!("10. Name support:");
133 let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134 println!(" Initial name: {:?}", named_consumer.name());
135
136 named_consumer.set_name("init_callback");
137 println!(" After setting name: {:?}", named_consumer.name());
138 println!(" Display: {}", named_consumer);
139 named_consumer.accept_once(&1, &2);
140 println!();
141
142 // 11. Print helpers
143 println!("11. Print helpers:");
144 let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145 print.accept_once(&42, &10);
146
147 let print_with =
148 BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149 print_with.accept_once(&800, &600);
150 println!();
151
152 // 12. Converting to function
153 println!("12. Converting to function:");
154 let log = Arc::new(Mutex::new(Vec::new()));
155 let l = log.clone();
156 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157 l.lock().unwrap().push(*x + *y);
158 });
159 let func = consumer.into_fn_once();
160 func(&7, &3);
161 println!(" Log: {:?}\n", *log.lock().unwrap());
162
163 println!("=== Demo Complete ===");
164}Sourcepub fn when<P>(self, predicate: P) -> BoxConditionalBiConsumerOnce<T, U>where
P: BiPredicate<T, U> + 'static,
pub fn when<P>(self, predicate: P) -> BoxConditionalBiConsumerOnce<T, U>where
P: BiPredicate<T, U> + 'static,
Creates a conditional bi-consumer
Returns a bi-consumer that only executes when a predicate is satisfied.
§Type Parameters
P- The predicate type
§Parameters
predicate- The condition to check. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original bi-predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T, y: &U| -> bool - A function pointer:
fn(&T, &U) -> bool - A
BoxBiPredicate<T, U> - Any type implementing
BiPredicate<T, U>
- A closure:
§Returns
Returns BoxConditionalBiConsumerOnce<T, U>
§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
l.lock().unwrap().push(*x + *y);
});
let conditional = consumer.when(|x: &i32, y: &i32| *x > 0 && *y > 0);
conditional.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);Examples found in repository?
18fn main() {
19 println!("=== BiConsumerOnce Demo ===\n");
20
21 // 1. Basic usage
22 println!("1. Basic usage:");
23 let log = Arc::new(Mutex::new(Vec::new()));
24 let l = log.clone();
25 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26 l.lock().unwrap().push(*x + *y);
27 println!(" Sum: {}", x + y);
28 });
29 consumer.accept_once(&10, &5);
30 println!(" Log: {:?}\n", *log.lock().unwrap());
31
32 // 2. Method chaining
33 println!("2. Method chaining:");
34 let log = Arc::new(Mutex::new(Vec::new()));
35 let l1 = log.clone();
36 let l2 = log.clone();
37 let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38 l1.lock().unwrap().push(*x + *y);
39 println!(" First: sum={}", x + y);
40 })
41 .and_then(move |x: &i32, y: &i32| {
42 l2.lock().unwrap().push(*x * *y);
43 println!(" Second: product={}", x * y);
44 });
45 chained.accept_once(&5, &3);
46 println!(" Log: {:?}\n", *log.lock().unwrap());
47
48 // 3. Conditional execution - true case
49 println!("3. Conditional execution - true case:");
50 let log = Arc::new(Mutex::new(Vec::new()));
51 let l = log.clone();
52 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53 l.lock().unwrap().push(*x + *y);
54 })
55 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56 conditional.accept_once(&5, &3);
57 println!(" Positive values: {:?}\n", *log.lock().unwrap());
58
59 // 4. Conditional execution - false case
60 println!("4. Conditional execution - false case:");
61 let log = Arc::new(Mutex::new(Vec::new()));
62 let l = log.clone();
63 let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64 l.lock().unwrap().push(*x + *y);
65 })
66 .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67 conditional.accept_once(&-5, &3);
68 println!(" Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70 // 5. Conditional branching
71 println!("5. Conditional branching:");
72 let log = Arc::new(Mutex::new(Vec::new()));
73 let l1 = log.clone();
74 let l2 = log.clone();
75 let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76 l1.lock().unwrap().push(*x);
77 })
78 .when(|x: &i32, y: &i32| *x > *y)
79 .or_else(move |_x: &i32, y: &i32| {
80 l2.lock().unwrap().push(*y);
81 });
82 branch.accept_once(&15, &10);
83 println!(" When x > y: {:?}\n", *log.lock().unwrap());
84
85 // 6. Working with closures directly
86 println!("6. Working with closures directly:");
87 let log = Arc::new(Mutex::new(Vec::new()));
88 let l = log.clone();
89 let closure = move |x: &i32, y: &i32| {
90 l.lock().unwrap().push(*x + *y);
91 println!(" Processed: {}", x + y);
92 };
93 closure.accept_once(&10, &20);
94 println!(" Log: {:?}\n", *log.lock().unwrap());
95
96 // 7. Moving captured values
97 println!("7. Moving captured values:");
98 let data = vec![1, 2, 3, 4, 5];
99 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100 println!(" x={}, y={}", x, y);
101 println!(" Captured data: {:?}", data);
102 println!(" Data sum: {}", data.iter().sum::<i32>());
103 });
104 consumer.accept_once(&5, &3);
105 // data is no longer available here
106 println!();
107
108 // 8. Initialization callback
109 println!("8. Initialization callback:");
110 let log = Arc::new(Mutex::new(Vec::new()));
111 let l = log.clone();
112 let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113 println!(" Initializing with dimensions: {}x{}", width, height);
114 l.lock().unwrap().push(*width * *height);
115 });
116 init_callback.accept_once(&800, &600);
117 println!(" Areas: {:?}\n", *log.lock().unwrap());
118
119 // 9. Cleanup callback
120 println!("9. Cleanup callback:");
121 let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122 println!(" Cleanup: processed {} out of {} items", count, total);
123 println!(
124 " Success rate: {:.1}%",
125 (*count as f64 / *total as f64) * 100.0
126 );
127 });
128 cleanup.accept_once(&85, &100);
129 println!();
130
131 // 10. Name support
132 println!("10. Name support:");
133 let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134 println!(" Initial name: {:?}", named_consumer.name());
135
136 named_consumer.set_name("init_callback");
137 println!(" After setting name: {:?}", named_consumer.name());
138 println!(" Display: {}", named_consumer);
139 named_consumer.accept_once(&1, &2);
140 println!();
141
142 // 11. Print helpers
143 println!("11. Print helpers:");
144 let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145 print.accept_once(&42, &10);
146
147 let print_with =
148 BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149 print_with.accept_once(&800, &600);
150 println!();
151
152 // 12. Converting to function
153 println!("12. Converting to function:");
154 let log = Arc::new(Mutex::new(Vec::new()));
155 let l = log.clone();
156 let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157 l.lock().unwrap().push(*x + *y);
158 });
159 let func = consumer.into_fn_once();
160 func(&7, &3);
161 println!(" Log: {:?}\n", *log.lock().unwrap());
162
163 println!("=== Demo Complete ===");
164}