use qubit_function::{
ArcBiConsumer,
BiConsumer,
BoxBiConsumer,
BoxStatefulBiConsumer,
RcBiConsumer,
StatefulBiConsumer,
};
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{
Arc,
Mutex,
};
use std::thread;
fn main() {
println!("=== BiConsumer Demo ===\n");
println!("1. BoxBiConsumer - Single ownership:");
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let box_consumer = BoxBiConsumer::new(move |x: &i32, y: &i32| {
println!(" Processing: x={}, y={}", x, y);
l.lock().unwrap().push(*x + *y);
});
box_consumer.accept(&10, &5);
println!(" Result log: {:?}\n", *log.lock().unwrap());
println!("2. BoxBiConsumer with method chaining:");
let log = Arc::new(Mutex::new(Vec::new()));
let l1 = log.clone();
let l2 = log.clone();
let chained = BoxBiConsumer::new(move |x: &i32, y: &i32| {
l1.lock().unwrap().push(*x + *y);
println!(" After first operation: sum = {}", x + y);
})
.and_then(move |x: &i32, y: &i32| {
l2.lock().unwrap().push(*x * *y);
println!(" After second operation: product = {}", x * y);
});
chained.accept(&5, &3);
println!(" Final log: {:?}\n", *log.lock().unwrap());
println!("3. ArcBiConsumer - Thread-safe shared ownership:");
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let arc_consumer = ArcBiConsumer::new(move |x: &i32, y: &i32| {
l.lock().unwrap().push(*x + *y);
println!(" Thread {:?}: sum = {}", thread::current().id(), x + y);
});
let consumer1 = arc_consumer.clone();
let consumer2 = arc_consumer.clone();
let handle1 = thread::spawn(move || {
let c = consumer1;
c.accept(&10, &5);
});
let handle2 = thread::spawn(move || {
let c = consumer2;
c.accept(&20, &8);
});
handle1.join().unwrap();
handle2.join().unwrap();
println!(" Final log: {:?}\n", *log.lock().unwrap());
println!("4. RcBiConsumer - Single-threaded shared ownership:");
let log = Rc::new(RefCell::new(Vec::new()));
let l = log.clone();
let rc_consumer = RcBiConsumer::new(move |x: &i32, y: &i32| {
l.borrow_mut().push(*x + *y);
});
let clone1 = rc_consumer.clone();
let clone2 = rc_consumer.clone();
clone1.accept(&5, &3);
println!(" After first use: {:?}", *log.borrow());
clone2.accept(&7, &2);
println!(" After second use: {:?}\n", *log.borrow());
println!("5. Working with closures directly:");
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32, y: &i32| {
let sum = *x + *y;
l.lock().unwrap().push(sum);
};
closure.accept(&10, &20);
println!(" After closure: {:?}\n", *log.lock().unwrap());
println!("6. Conditional BiConsumer:");
let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let mut conditional = BoxStatefulBiConsumer::new(move |x: &i32, y: &i32| {
l.lock().unwrap().push(*x + *y);
})
.when(|x: &i32, y: &i32| *x > 0 && *y > 0);
conditional.accept(&5, &3);
println!(" Positive values: {:?}", *log.lock().unwrap());
conditional.accept(&-5, &3);
println!(" Negative value (unchanged): {:?}\n", *log.lock().unwrap());
println!("7. Conditional branch BiConsumer:");
let log = Arc::new(Mutex::new(Vec::new()));
let l1 = log.clone();
let l2 = log.clone();
let mut branch = BoxStatefulBiConsumer::new(move |x: &i32, _y: &i32| {
l1.lock().unwrap().push(*x);
})
.when(|x: &i32, y: &i32| *x > *y)
.or_else(move |_x: &i32, y: &i32| {
l2.lock().unwrap().push(*y);
});
branch.accept(&15, &10);
println!(" When x > y: {:?}", *log.lock().unwrap());
branch.accept(&5, &10);
println!(" When x <= y: {:?}\n", *log.lock().unwrap());
println!("8. Accumulating statistics:");
let count = Arc::new(Mutex::new(0));
let sum = Arc::new(Mutex::new(0));
let c = count.clone();
let s = sum.clone();
let stats_consumer = BoxBiConsumer::new(move |x: &i32, y: &i32| {
*c.lock().unwrap() += 1;
*s.lock().unwrap() += x + y;
});
stats_consumer.accept(&5, &3);
stats_consumer.accept(&10, &2);
stats_consumer.accept(&7, &8);
println!(" Count: {}", *count.lock().unwrap());
println!(" Sum: {}\n", *sum.lock().unwrap());
println!("9. Name support:");
let mut named_consumer = BoxBiConsumer::<i32, i32>::noop();
println!(" Initial name: {:?}", named_consumer.name());
named_consumer.set_name("sum_calculator");
println!(" After setting name: {:?}", named_consumer.name());
println!(" Display: {}\n", named_consumer);
println!("=== Demo Complete ===");
}