BoxReadonlyBiConsumer

Struct BoxReadonlyBiConsumer 

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

Source

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

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

pub fn noop() -> Self

Creates a no-op readonly bi-consumer

§Returns

Returns a no-op readonly bi-consumer

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

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

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

pub fn and_then<C>(self, next: C) -> Self
where 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 implements Clone). 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>
§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>

Source§

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

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

impl<T, U> Display for BoxReadonlyBiConsumer<T, U>

Source§

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

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

impl<T, U> ReadonlyBiConsumer<T, U> for BoxReadonlyBiConsumer<T, U>

Source§

fn accept(&self, first: &T, second: &U)

Performs the readonly consumption operation Read more
Source§

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,

Converts to RcReadonlyBiConsumer Read more
Source§

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

Converts readonly bi-consumer to a closure Read more
Source§

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

Converts to ArcReadonlyBiConsumer 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> 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.