readonly_bi_consumer_demo/
readonly_bi_consumer_demo.rs1use prism3_function::{
16 ArcReadonlyBiConsumer, BoxReadonlyBiConsumer, RcReadonlyBiConsumer, ReadonlyBiConsumer,
17};
18use std::rc::Rc;
19use std::sync::{atomic::AtomicUsize, atomic::Ordering, Arc};
20use std::thread;
21
22fn main() {
23 println!("=== ReadonlyBiConsumer Demo ===\n");
24
25 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 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 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 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 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 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 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 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 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 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 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}