pub struct BoxReadonlyBiConsumer<T, U> { /* private fields */ }Expand description
BoxReadonlyBiConsumer struct
A readonly bi-consumer implementation based on Box<dyn Fn(&T, &U)>
for single ownership scenarios.
§Features
- Single Ownership: Not cloneable, ownership moves on use
- Zero Overhead: No reference counting or locking
- Fully Immutable: Neither modifies itself nor input values
- No Interior Mutability: No need for Mutex or RefCell
§Use Cases
Choose BoxReadonlyBiConsumer when:
- The readonly bi-consumer is used only once or in a linear flow
- No need to share the consumer across contexts
- Pure observation operations like logging
§Examples
use prism3_function::{ReadonlyBiConsumer, BoxReadonlyBiConsumer};
let consumer = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
println!("Sum: {}", x + y);
});
consumer.accept(&5, &3);§Author
Haixing Hu
Implementations§
Source§impl<T, U> BoxReadonlyBiConsumer<T, U>where
T: 'static,
U: 'static,
impl<T, U> BoxReadonlyBiConsumer<T, U>where
T: 'static,
U: 'static,
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new BoxReadonlyBiConsumer
§Type Parameters
F- The closure type
§Parameters
f- The closure to wrap
§Returns
Returns a new BoxReadonlyBiConsumer<T, U> instance
§Examples
use prism3_function::{ReadonlyBiConsumer, BoxReadonlyBiConsumer};
let consumer = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
println!("Product: {}", x * y);
});
consumer.accept(&5, &3);Examples found in repository?
examples/readonly_bi_consumer_demo.rs (lines 27-29)
22fn main() {
23 println!("=== ReadonlyBiConsumer Demo ===\n");
24
25 // 1. BoxReadonlyBiConsumer - Single ownership
26 println!("1. BoxReadonlyBiConsumer - Single ownership:");
27 let box_consumer = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
28 println!(" Values: x={}, y={}, sum={}", x, y, x + y);
29 });
30 box_consumer.accept(&10, &5);
31 println!();
32
33 // 2. Method chaining with BoxReadonlyBiConsumer
34 println!("2. BoxReadonlyBiConsumer with method chaining:");
35 let chained = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
36 println!(" First operation: x={}, y={}", x, y);
37 })
38 .and_then(|x: &i32, y: &i32| {
39 println!(" Second operation: sum={}", x + y);
40 })
41 .and_then(|x: &i32, y: &i32| {
42 println!(" Third operation: product={}", x * y);
43 });
44 chained.accept(&5, &3);
45 println!();
46
47 // 3. ArcReadonlyBiConsumer - Thread-safe shared ownership
48 println!("3. ArcReadonlyBiConsumer - Thread-safe shared ownership:");
49 let counter = Arc::new(AtomicUsize::new(0));
50 let c = counter.clone();
51 let arc_consumer = ArcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
52 c.fetch_add(1, Ordering::SeqCst);
53 println!(" Thread {:?}: sum={}", thread::current().id(), x + y);
54 });
55
56 let consumer1 = arc_consumer.clone();
57 let consumer2 = arc_consumer.clone();
58
59 let handle1 = thread::spawn(move || {
60 consumer1.accept(&10, &5);
61 });
62
63 let handle2 = thread::spawn(move || {
64 consumer2.accept(&20, &8);
65 });
66
67 handle1.join().unwrap();
68 handle2.join().unwrap();
69 println!(" Total calls: {}\n", counter.load(Ordering::SeqCst));
70
71 // 4. RcReadonlyBiConsumer - Single-threaded shared ownership
72 println!("4. RcReadonlyBiConsumer - Single-threaded shared ownership:");
73 let counter = Rc::new(std::cell::Cell::new(0));
74 let c = counter.clone();
75 let rc_consumer = RcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
76 c.set(c.get() + 1);
77 println!(" Call {}: sum={}", c.get(), x + y);
78 });
79
80 let clone1 = rc_consumer.clone();
81 let clone2 = rc_consumer.clone();
82
83 clone1.accept(&5, &3);
84 clone2.accept(&7, &2);
85 println!(" Total calls: {}\n", counter.get());
86
87 // 5. Working with closures directly
88 println!("5. Working with closures directly:");
89 let closure = |x: &i32, y: &i32| {
90 println!(" x={}, y={}, product={}", x, y, x * y);
91 };
92 closure.accept(&10, &20);
93 println!();
94
95 // 6. Pure observation - logging
96 println!("6. Pure observation - logging:");
97 let logger = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
98 println!(" [LOG] Processing pair: ({}, {})", x, y);
99 });
100 logger.accept(&5, &3);
101 logger.accept(&10, &7);
102 println!();
103
104 // 7. Chaining observations
105 println!("7. Chaining observations:");
106 let log_input = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
107 println!(" [INPUT] x={}, y={}", x, y);
108 });
109 let log_sum = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
110 println!(" [SUM] {}", x + y);
111 });
112 let log_product = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
113 println!(" [PRODUCT] {}", x * y);
114 });
115
116 let chained = log_input.and_then(log_sum).and_then(log_product);
117 chained.accept(&5, &3);
118 println!();
119
120 // 8. ArcReadonlyBiConsumer - Reusability
121 println!("8. ArcReadonlyBiConsumer - Reusability:");
122 let first = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
123 println!(" First: x={}, y={}", x, y);
124 });
125 let second = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
126 println!(" Second: sum={}", x + y);
127 });
128
129 // Both first and second can be reused after chaining
130 let chained1 = first.and_then(&second);
131 let chained2 = first.and_then(&second);
132
133 println!(" Using chained1:");
134 chained1.accept(&5, &3);
135
136 println!(" Using chained2:");
137 chained2.accept(&10, &2);
138 println!();
139
140 // 9. Name support
141 println!("9. Name support:");
142 let mut named_consumer = BoxReadonlyBiConsumer::<i32, i32>::noop();
143 println!(" Initial name: {:?}", named_consumer.name());
144
145 named_consumer.set_name("sum_logger");
146 println!(" After setting name: {:?}", named_consumer.name());
147 println!(" Display: {}\n", named_consumer);
148
149 // 10. No-op consumer
150 println!("10. No-op consumer:");
151 let noop = BoxReadonlyBiConsumer::<i32, i32>::noop();
152 noop.accept(&42, &10);
153 println!(" No-op completed (no output expected)\n");
154
155 println!("=== Demo Complete ===");
156}Sourcepub fn noop() -> Self
pub fn noop() -> Self
Examples found in repository?
examples/readonly_bi_consumer_demo.rs (line 142)
22fn main() {
23 println!("=== ReadonlyBiConsumer Demo ===\n");
24
25 // 1. BoxReadonlyBiConsumer - Single ownership
26 println!("1. BoxReadonlyBiConsumer - Single ownership:");
27 let box_consumer = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
28 println!(" Values: x={}, y={}, sum={}", x, y, x + y);
29 });
30 box_consumer.accept(&10, &5);
31 println!();
32
33 // 2. Method chaining with BoxReadonlyBiConsumer
34 println!("2. BoxReadonlyBiConsumer with method chaining:");
35 let chained = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
36 println!(" First operation: x={}, y={}", x, y);
37 })
38 .and_then(|x: &i32, y: &i32| {
39 println!(" Second operation: sum={}", x + y);
40 })
41 .and_then(|x: &i32, y: &i32| {
42 println!(" Third operation: product={}", x * y);
43 });
44 chained.accept(&5, &3);
45 println!();
46
47 // 3. ArcReadonlyBiConsumer - Thread-safe shared ownership
48 println!("3. ArcReadonlyBiConsumer - Thread-safe shared ownership:");
49 let counter = Arc::new(AtomicUsize::new(0));
50 let c = counter.clone();
51 let arc_consumer = ArcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
52 c.fetch_add(1, Ordering::SeqCst);
53 println!(" Thread {:?}: sum={}", thread::current().id(), x + y);
54 });
55
56 let consumer1 = arc_consumer.clone();
57 let consumer2 = arc_consumer.clone();
58
59 let handle1 = thread::spawn(move || {
60 consumer1.accept(&10, &5);
61 });
62
63 let handle2 = thread::spawn(move || {
64 consumer2.accept(&20, &8);
65 });
66
67 handle1.join().unwrap();
68 handle2.join().unwrap();
69 println!(" Total calls: {}\n", counter.load(Ordering::SeqCst));
70
71 // 4. RcReadonlyBiConsumer - Single-threaded shared ownership
72 println!("4. RcReadonlyBiConsumer - Single-threaded shared ownership:");
73 let counter = Rc::new(std::cell::Cell::new(0));
74 let c = counter.clone();
75 let rc_consumer = RcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
76 c.set(c.get() + 1);
77 println!(" Call {}: sum={}", c.get(), x + y);
78 });
79
80 let clone1 = rc_consumer.clone();
81 let clone2 = rc_consumer.clone();
82
83 clone1.accept(&5, &3);
84 clone2.accept(&7, &2);
85 println!(" Total calls: {}\n", counter.get());
86
87 // 5. Working with closures directly
88 println!("5. Working with closures directly:");
89 let closure = |x: &i32, y: &i32| {
90 println!(" x={}, y={}, product={}", x, y, x * y);
91 };
92 closure.accept(&10, &20);
93 println!();
94
95 // 6. Pure observation - logging
96 println!("6. Pure observation - logging:");
97 let logger = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
98 println!(" [LOG] Processing pair: ({}, {})", x, y);
99 });
100 logger.accept(&5, &3);
101 logger.accept(&10, &7);
102 println!();
103
104 // 7. Chaining observations
105 println!("7. Chaining observations:");
106 let log_input = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
107 println!(" [INPUT] x={}, y={}", x, y);
108 });
109 let log_sum = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
110 println!(" [SUM] {}", x + y);
111 });
112 let log_product = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
113 println!(" [PRODUCT] {}", x * y);
114 });
115
116 let chained = log_input.and_then(log_sum).and_then(log_product);
117 chained.accept(&5, &3);
118 println!();
119
120 // 8. ArcReadonlyBiConsumer - Reusability
121 println!("8. ArcReadonlyBiConsumer - Reusability:");
122 let first = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
123 println!(" First: x={}, y={}", x, y);
124 });
125 let second = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
126 println!(" Second: sum={}", x + y);
127 });
128
129 // Both first and second can be reused after chaining
130 let chained1 = first.and_then(&second);
131 let chained2 = first.and_then(&second);
132
133 println!(" Using chained1:");
134 chained1.accept(&5, &3);
135
136 println!(" Using chained2:");
137 chained2.accept(&10, &2);
138 println!();
139
140 // 9. Name support
141 println!("9. Name support:");
142 let mut named_consumer = BoxReadonlyBiConsumer::<i32, i32>::noop();
143 println!(" Initial name: {:?}", named_consumer.name());
144
145 named_consumer.set_name("sum_logger");
146 println!(" After setting name: {:?}", named_consumer.name());
147 println!(" Display: {}\n", named_consumer);
148
149 // 10. No-op consumer
150 println!("10. No-op consumer:");
151 let noop = BoxReadonlyBiConsumer::<i32, i32>::noop();
152 noop.accept(&42, &10);
153 println!(" No-op completed (no output expected)\n");
154
155 println!("=== Demo Complete ===");
156}Sourcepub fn name(&self) -> Option<&str>
pub fn name(&self) -> Option<&str>
Gets the name of the consumer
Examples found in repository?
examples/readonly_bi_consumer_demo.rs (line 143)
22fn main() {
23 println!("=== ReadonlyBiConsumer Demo ===\n");
24
25 // 1. BoxReadonlyBiConsumer - Single ownership
26 println!("1. BoxReadonlyBiConsumer - Single ownership:");
27 let box_consumer = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
28 println!(" Values: x={}, y={}, sum={}", x, y, x + y);
29 });
30 box_consumer.accept(&10, &5);
31 println!();
32
33 // 2. Method chaining with BoxReadonlyBiConsumer
34 println!("2. BoxReadonlyBiConsumer with method chaining:");
35 let chained = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
36 println!(" First operation: x={}, y={}", x, y);
37 })
38 .and_then(|x: &i32, y: &i32| {
39 println!(" Second operation: sum={}", x + y);
40 })
41 .and_then(|x: &i32, y: &i32| {
42 println!(" Third operation: product={}", x * y);
43 });
44 chained.accept(&5, &3);
45 println!();
46
47 // 3. ArcReadonlyBiConsumer - Thread-safe shared ownership
48 println!("3. ArcReadonlyBiConsumer - Thread-safe shared ownership:");
49 let counter = Arc::new(AtomicUsize::new(0));
50 let c = counter.clone();
51 let arc_consumer = ArcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
52 c.fetch_add(1, Ordering::SeqCst);
53 println!(" Thread {:?}: sum={}", thread::current().id(), x + y);
54 });
55
56 let consumer1 = arc_consumer.clone();
57 let consumer2 = arc_consumer.clone();
58
59 let handle1 = thread::spawn(move || {
60 consumer1.accept(&10, &5);
61 });
62
63 let handle2 = thread::spawn(move || {
64 consumer2.accept(&20, &8);
65 });
66
67 handle1.join().unwrap();
68 handle2.join().unwrap();
69 println!(" Total calls: {}\n", counter.load(Ordering::SeqCst));
70
71 // 4. RcReadonlyBiConsumer - Single-threaded shared ownership
72 println!("4. RcReadonlyBiConsumer - Single-threaded shared ownership:");
73 let counter = Rc::new(std::cell::Cell::new(0));
74 let c = counter.clone();
75 let rc_consumer = RcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
76 c.set(c.get() + 1);
77 println!(" Call {}: sum={}", c.get(), x + y);
78 });
79
80 let clone1 = rc_consumer.clone();
81 let clone2 = rc_consumer.clone();
82
83 clone1.accept(&5, &3);
84 clone2.accept(&7, &2);
85 println!(" Total calls: {}\n", counter.get());
86
87 // 5. Working with closures directly
88 println!("5. Working with closures directly:");
89 let closure = |x: &i32, y: &i32| {
90 println!(" x={}, y={}, product={}", x, y, x * y);
91 };
92 closure.accept(&10, &20);
93 println!();
94
95 // 6. Pure observation - logging
96 println!("6. Pure observation - logging:");
97 let logger = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
98 println!(" [LOG] Processing pair: ({}, {})", x, y);
99 });
100 logger.accept(&5, &3);
101 logger.accept(&10, &7);
102 println!();
103
104 // 7. Chaining observations
105 println!("7. Chaining observations:");
106 let log_input = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
107 println!(" [INPUT] x={}, y={}", x, y);
108 });
109 let log_sum = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
110 println!(" [SUM] {}", x + y);
111 });
112 let log_product = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
113 println!(" [PRODUCT] {}", x * y);
114 });
115
116 let chained = log_input.and_then(log_sum).and_then(log_product);
117 chained.accept(&5, &3);
118 println!();
119
120 // 8. ArcReadonlyBiConsumer - Reusability
121 println!("8. ArcReadonlyBiConsumer - Reusability:");
122 let first = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
123 println!(" First: x={}, y={}", x, y);
124 });
125 let second = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
126 println!(" Second: sum={}", x + y);
127 });
128
129 // Both first and second can be reused after chaining
130 let chained1 = first.and_then(&second);
131 let chained2 = first.and_then(&second);
132
133 println!(" Using chained1:");
134 chained1.accept(&5, &3);
135
136 println!(" Using chained2:");
137 chained2.accept(&10, &2);
138 println!();
139
140 // 9. Name support
141 println!("9. Name support:");
142 let mut named_consumer = BoxReadonlyBiConsumer::<i32, i32>::noop();
143 println!(" Initial name: {:?}", named_consumer.name());
144
145 named_consumer.set_name("sum_logger");
146 println!(" After setting name: {:?}", named_consumer.name());
147 println!(" Display: {}\n", named_consumer);
148
149 // 10. No-op consumer
150 println!("10. No-op consumer:");
151 let noop = BoxReadonlyBiConsumer::<i32, i32>::noop();
152 noop.accept(&42, &10);
153 println!(" No-op completed (no output expected)\n");
154
155 println!("=== Demo Complete ===");
156}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?
examples/readonly_bi_consumer_demo.rs (line 145)
22fn main() {
23 println!("=== ReadonlyBiConsumer Demo ===\n");
24
25 // 1. BoxReadonlyBiConsumer - Single ownership
26 println!("1. BoxReadonlyBiConsumer - Single ownership:");
27 let box_consumer = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
28 println!(" Values: x={}, y={}, sum={}", x, y, x + y);
29 });
30 box_consumer.accept(&10, &5);
31 println!();
32
33 // 2. Method chaining with BoxReadonlyBiConsumer
34 println!("2. BoxReadonlyBiConsumer with method chaining:");
35 let chained = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
36 println!(" First operation: x={}, y={}", x, y);
37 })
38 .and_then(|x: &i32, y: &i32| {
39 println!(" Second operation: sum={}", x + y);
40 })
41 .and_then(|x: &i32, y: &i32| {
42 println!(" Third operation: product={}", x * y);
43 });
44 chained.accept(&5, &3);
45 println!();
46
47 // 3. ArcReadonlyBiConsumer - Thread-safe shared ownership
48 println!("3. ArcReadonlyBiConsumer - Thread-safe shared ownership:");
49 let counter = Arc::new(AtomicUsize::new(0));
50 let c = counter.clone();
51 let arc_consumer = ArcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
52 c.fetch_add(1, Ordering::SeqCst);
53 println!(" Thread {:?}: sum={}", thread::current().id(), x + y);
54 });
55
56 let consumer1 = arc_consumer.clone();
57 let consumer2 = arc_consumer.clone();
58
59 let handle1 = thread::spawn(move || {
60 consumer1.accept(&10, &5);
61 });
62
63 let handle2 = thread::spawn(move || {
64 consumer2.accept(&20, &8);
65 });
66
67 handle1.join().unwrap();
68 handle2.join().unwrap();
69 println!(" Total calls: {}\n", counter.load(Ordering::SeqCst));
70
71 // 4. RcReadonlyBiConsumer - Single-threaded shared ownership
72 println!("4. RcReadonlyBiConsumer - Single-threaded shared ownership:");
73 let counter = Rc::new(std::cell::Cell::new(0));
74 let c = counter.clone();
75 let rc_consumer = RcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
76 c.set(c.get() + 1);
77 println!(" Call {}: sum={}", c.get(), x + y);
78 });
79
80 let clone1 = rc_consumer.clone();
81 let clone2 = rc_consumer.clone();
82
83 clone1.accept(&5, &3);
84 clone2.accept(&7, &2);
85 println!(" Total calls: {}\n", counter.get());
86
87 // 5. Working with closures directly
88 println!("5. Working with closures directly:");
89 let closure = |x: &i32, y: &i32| {
90 println!(" x={}, y={}, product={}", x, y, x * y);
91 };
92 closure.accept(&10, &20);
93 println!();
94
95 // 6. Pure observation - logging
96 println!("6. Pure observation - logging:");
97 let logger = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
98 println!(" [LOG] Processing pair: ({}, {})", x, y);
99 });
100 logger.accept(&5, &3);
101 logger.accept(&10, &7);
102 println!();
103
104 // 7. Chaining observations
105 println!("7. Chaining observations:");
106 let log_input = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
107 println!(" [INPUT] x={}, y={}", x, y);
108 });
109 let log_sum = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
110 println!(" [SUM] {}", x + y);
111 });
112 let log_product = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
113 println!(" [PRODUCT] {}", x * y);
114 });
115
116 let chained = log_input.and_then(log_sum).and_then(log_product);
117 chained.accept(&5, &3);
118 println!();
119
120 // 8. ArcReadonlyBiConsumer - Reusability
121 println!("8. ArcReadonlyBiConsumer - Reusability:");
122 let first = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
123 println!(" First: x={}, y={}", x, y);
124 });
125 let second = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
126 println!(" Second: sum={}", x + y);
127 });
128
129 // Both first and second can be reused after chaining
130 let chained1 = first.and_then(&second);
131 let chained2 = first.and_then(&second);
132
133 println!(" Using chained1:");
134 chained1.accept(&5, &3);
135
136 println!(" Using chained2:");
137 chained2.accept(&10, &2);
138 println!();
139
140 // 9. Name support
141 println!("9. Name support:");
142 let mut named_consumer = BoxReadonlyBiConsumer::<i32, i32>::noop();
143 println!(" Initial name: {:?}", named_consumer.name());
144
145 named_consumer.set_name("sum_logger");
146 println!(" After setting name: {:?}", named_consumer.name());
147 println!(" Display: {}\n", named_consumer);
148
149 // 10. No-op consumer
150 println!("10. No-op consumer:");
151 let noop = BoxReadonlyBiConsumer::<i32, i32>::noop();
152 noop.accept(&42, &10);
153 println!(" No-op completed (no output expected)\n");
154
155 println!("=== Demo Complete ===");
156}Sourcepub fn and_then<C>(self, next: C) -> Selfwhere
C: ReadonlyBiConsumer<T, U> + 'static,
pub fn and_then<C>(self, next: C) -> Selfwhere
C: ReadonlyBiConsumer<T, U> + 'static,
Chains another readonly 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. If you need to preserve the original consumer, clone it first (if it implementsClone). Can be:- A closure:
|x: &T, y: &U| - A
BoxReadonlyBiConsumer<T, U> - An
RcReadonlyBiConsumer<T, U> - An
ArcReadonlyBiConsumer<T, U> - Any type implementing
ReadonlyBiConsumer<T, U>
- A closure:
§Returns
Returns a new composed BoxReadonlyBiConsumer<T, U>
§Examples
§Direct value passing (ownership transfer)
use prism3_function::{ReadonlyBiConsumer, BoxReadonlyBiConsumer};
let first = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
println!("First: {}, {}", x, y);
});
let second = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
println!("Second: sum = {}", x + y);
});
// second is moved here
let chained = first.and_then(second);
chained.accept(&5, &3);
// second.accept(&2, &3); // Would not compile - moved§Preserving original with clone
use prism3_function::{ReadonlyBiConsumer, BoxReadonlyBiConsumer, RcReadonlyBiConsumer};
let first = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
println!("First: {}, {}", x, y);
});
let second = RcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
println!("Second: sum = {}", x + y);
});
// Clone to preserve original
let chained = first.and_then(second.clone());
chained.accept(&5, &3);
// Original still usable
second.accept(&2, &3);Examples found in repository?
examples/readonly_bi_consumer_demo.rs (lines 38-40)
22fn main() {
23 println!("=== ReadonlyBiConsumer Demo ===\n");
24
25 // 1. BoxReadonlyBiConsumer - Single ownership
26 println!("1. BoxReadonlyBiConsumer - Single ownership:");
27 let box_consumer = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
28 println!(" Values: x={}, y={}, sum={}", x, y, x + y);
29 });
30 box_consumer.accept(&10, &5);
31 println!();
32
33 // 2. Method chaining with BoxReadonlyBiConsumer
34 println!("2. BoxReadonlyBiConsumer with method chaining:");
35 let chained = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
36 println!(" First operation: x={}, y={}", x, y);
37 })
38 .and_then(|x: &i32, y: &i32| {
39 println!(" Second operation: sum={}", x + y);
40 })
41 .and_then(|x: &i32, y: &i32| {
42 println!(" Third operation: product={}", x * y);
43 });
44 chained.accept(&5, &3);
45 println!();
46
47 // 3. ArcReadonlyBiConsumer - Thread-safe shared ownership
48 println!("3. ArcReadonlyBiConsumer - Thread-safe shared ownership:");
49 let counter = Arc::new(AtomicUsize::new(0));
50 let c = counter.clone();
51 let arc_consumer = ArcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
52 c.fetch_add(1, Ordering::SeqCst);
53 println!(" Thread {:?}: sum={}", thread::current().id(), x + y);
54 });
55
56 let consumer1 = arc_consumer.clone();
57 let consumer2 = arc_consumer.clone();
58
59 let handle1 = thread::spawn(move || {
60 consumer1.accept(&10, &5);
61 });
62
63 let handle2 = thread::spawn(move || {
64 consumer2.accept(&20, &8);
65 });
66
67 handle1.join().unwrap();
68 handle2.join().unwrap();
69 println!(" Total calls: {}\n", counter.load(Ordering::SeqCst));
70
71 // 4. RcReadonlyBiConsumer - Single-threaded shared ownership
72 println!("4. RcReadonlyBiConsumer - Single-threaded shared ownership:");
73 let counter = Rc::new(std::cell::Cell::new(0));
74 let c = counter.clone();
75 let rc_consumer = RcReadonlyBiConsumer::new(move |x: &i32, y: &i32| {
76 c.set(c.get() + 1);
77 println!(" Call {}: sum={}", c.get(), x + y);
78 });
79
80 let clone1 = rc_consumer.clone();
81 let clone2 = rc_consumer.clone();
82
83 clone1.accept(&5, &3);
84 clone2.accept(&7, &2);
85 println!(" Total calls: {}\n", counter.get());
86
87 // 5. Working with closures directly
88 println!("5. Working with closures directly:");
89 let closure = |x: &i32, y: &i32| {
90 println!(" x={}, y={}, product={}", x, y, x * y);
91 };
92 closure.accept(&10, &20);
93 println!();
94
95 // 6. Pure observation - logging
96 println!("6. Pure observation - logging:");
97 let logger = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
98 println!(" [LOG] Processing pair: ({}, {})", x, y);
99 });
100 logger.accept(&5, &3);
101 logger.accept(&10, &7);
102 println!();
103
104 // 7. Chaining observations
105 println!("7. Chaining observations:");
106 let log_input = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
107 println!(" [INPUT] x={}, y={}", x, y);
108 });
109 let log_sum = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
110 println!(" [SUM] {}", x + y);
111 });
112 let log_product = BoxReadonlyBiConsumer::new(|x: &i32, y: &i32| {
113 println!(" [PRODUCT] {}", x * y);
114 });
115
116 let chained = log_input.and_then(log_sum).and_then(log_product);
117 chained.accept(&5, &3);
118 println!();
119
120 // 8. ArcReadonlyBiConsumer - Reusability
121 println!("8. ArcReadonlyBiConsumer - Reusability:");
122 let first = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
123 println!(" First: x={}, y={}", x, y);
124 });
125 let second = ArcReadonlyBiConsumer::new(|x: &i32, y: &i32| {
126 println!(" Second: sum={}", x + y);
127 });
128
129 // Both first and second can be reused after chaining
130 let chained1 = first.and_then(&second);
131 let chained2 = first.and_then(&second);
132
133 println!(" Using chained1:");
134 chained1.accept(&5, &3);
135
136 println!(" Using chained2:");
137 chained2.accept(&10, &2);
138 println!();
139
140 // 9. Name support
141 println!("9. Name support:");
142 let mut named_consumer = BoxReadonlyBiConsumer::<i32, i32>::noop();
143 println!(" Initial name: {:?}", named_consumer.name());
144
145 named_consumer.set_name("sum_logger");
146 println!(" After setting name: {:?}", named_consumer.name());
147 println!(" Display: {}\n", named_consumer);
148
149 // 10. No-op consumer
150 println!("10. No-op consumer:");
151 let noop = BoxReadonlyBiConsumer::<i32, i32>::noop();
152 noop.accept(&42, &10);
153 println!(" No-op completed (no output expected)\n");
154
155 println!("=== Demo Complete ===");
156}Trait Implementations§
Source§impl<T, U> Debug for BoxReadonlyBiConsumer<T, U>
impl<T, U> Debug for BoxReadonlyBiConsumer<T, U>
Source§impl<T, U> Display for BoxReadonlyBiConsumer<T, U>
impl<T, U> Display for BoxReadonlyBiConsumer<T, U>
Source§impl<T, U> ReadonlyBiConsumer<T, U> for BoxReadonlyBiConsumer<T, U>
impl<T, U> ReadonlyBiConsumer<T, U> for BoxReadonlyBiConsumer<T, U>
Source§fn into_box(self) -> BoxReadonlyBiConsumer<T, U>where
T: 'static,
U: 'static,
fn into_box(self) -> BoxReadonlyBiConsumer<T, U>where
T: 'static,
U: 'static,
Converts to BoxReadonlyBiConsumer Read more
Source§fn into_rc(self) -> RcReadonlyBiConsumer<T, U>where
T: 'static,
U: 'static,
fn into_rc(self) -> RcReadonlyBiConsumer<T, U>where
T: 'static,
U: 'static,
Converts to RcReadonlyBiConsumer Read more
Auto Trait Implementations§
impl<T, U> Freeze for BoxReadonlyBiConsumer<T, U>
impl<T, U> !RefUnwindSafe for BoxReadonlyBiConsumer<T, U>
impl<T, U> !Send for BoxReadonlyBiConsumer<T, U>
impl<T, U> !Sync for BoxReadonlyBiConsumer<T, U>
impl<T, U> Unpin for BoxReadonlyBiConsumer<T, U>
impl<T, U> !UnwindSafe for BoxReadonlyBiConsumer<T, U>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more