use qubit_function::{
ArcConsumer,
BoxConsumer,
BoxStatefulConsumer,
Consumer,
FnConsumerOps,
RcConsumer,
StatefulConsumer,
};
use std::sync::{
Arc,
Mutex,
};
use std::thread;
fn main() {
println!("=== Consumer Examples ===\n");
println!("Note: Consumer only reads values, does not modify the original value");
println!("If you need to modify values, please refer to mutator_demo.rs\n");
println!("Example 1: BoxConsumer basic usage");
println!("{}", "-".repeat(50));
let consumer = BoxConsumer::new(|x: &i32| {
println!("Read and calculate: {} * 2 = {}", x, x * 2);
});
let value = 5;
println!("Value: {}", value);
consumer.accept(&value);
println!("Value remains: {} (not modified)\n", value);
println!("Example 2: BoxConsumer method chaining");
println!("{}", "-".repeat(50));
let results = Arc::new(Mutex::new(Vec::new()));
let r1 = results.clone();
let r2 = results.clone();
let r3 = results.clone();
let chained = BoxConsumer::new(move |x: &i32| {
r1.lock().unwrap().push(*x * 2);
})
.and_then(move |x: &i32| {
r2.lock().unwrap().push(*x + 10);
})
.and_then(move |x: &i32| {
r3.lock().unwrap().push(*x);
println!("Processing value: {}", x);
});
let value = 5;
println!("Initial value: {}", value);
chained.accept(&value);
println!("Collected results: {:?}", *results.lock().unwrap());
println!("Original value: {} (not modified)\n", value);
println!("Example 3: Direct use of extension methods on closures");
println!("{}", "-".repeat(50));
let result = Arc::new(Mutex::new(0));
let r1 = result.clone();
let r2 = result.clone();
let closure_chain = (move |x: &i32| {
*r1.lock().unwrap() = *x * 2;
})
.and_then(move |_x: &i32| {
*r2.lock().unwrap() += 10;
});
let value = 5;
println!("Initial value: {}", value);
closure_chain.accept(&value);
println!("Calculation result: {}", *result.lock().unwrap());
println!("Original value: {} (not modified)\n", value);
println!("Example 4: BoxConsumer factory methods");
println!("{}", "-".repeat(50));
println!("noop - does nothing:");
let noop = BoxConsumer::<i32>::noop();
let value = 42;
noop.accept(&value);
println!("Value: {}\n", value);
print!("print - prints value: ");
let print = BoxConsumer::new(|x: &i32| println!("{}", x));
let value = 42;
print.accept(&value);
println!();
let print_with = BoxConsumer::new(|x: &i32| println!("Value is: {}", x));
let value = 42;
print_with.accept(&value);
println!();
println!("Example 5: Conditional Consumer");
println!("{}", "-".repeat(50));
let mut check_positive =
BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x)).when(|x: &i32| *x > 0);
let positive = 5;
let negative = -5;
print!("Check {}: ", positive);
check_positive.accept(&positive);
print!("Check {}: ", negative);
check_positive.accept(&negative);
println!("(negative numbers not printed)\n");
let mut categorize = BoxStatefulConsumer::new(|x: &i32| println!("Positive: {}", x))
.when(|x: &i32| *x > 0)
.or_else(|x: &i32| println!("Non-positive: {}", x));
let positive = 10;
let negative = -10;
categorize.accept(&positive);
categorize.accept(&negative);
println!();
println!("Example 6: ArcConsumer - multi-threaded sharing");
println!("{}", "-".repeat(50));
let shared = ArcConsumer::new(|x: &i32| println!("Processing value: {}", x * 2));
let shared_clone = shared.clone();
let handle = thread::spawn(move || {
let value = 5;
let consumer = shared_clone;
consumer.accept(&value);
value
});
let value = 3;
let consumer = shared;
consumer.accept(&value);
let thread_result = handle.join().unwrap();
println!("Thread result: {}\n", thread_result);
println!("Example 7: ArcConsumer composition (borrowing &self)");
println!("{}", "-".repeat(50));
let double = ArcConsumer::new(|x: &i32| println!("double: {}", x * 2));
let add_ten = ArcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
let pipeline1 = double.and_then(add_ten.clone());
let pipeline2 = add_ten.and_then(double.clone());
let value1 = 5;
let p1 = pipeline1;
print!("pipeline1 processing 5: ");
p1.accept(&value1);
let value2 = 5;
let p2 = pipeline2;
print!("pipeline2 processing 5: ");
p2.accept(&value2);
let value3 = 10;
let d = double;
print!("Original double still available, processing 10: ");
d.accept(&value3);
println!();
println!("Example 8: RcConsumer - single-threaded sharing");
println!("{}", "-".repeat(50));
let rc_consumer = RcConsumer::new(|x: &i32| println!("Processing: {}", x * 2));
let clone1 = rc_consumer.clone();
let clone2 = rc_consumer.clone();
let value1 = 5;
let c1 = clone1;
print!("clone1 processing 5: ");
c1.accept(&value1);
let value2 = 3;
let c2 = clone2;
print!("clone2 processing 3: ");
c2.accept(&value2);
let value3 = 7;
let c3 = rc_consumer;
print!("Original processing 7: ");
c3.accept(&value3);
println!();
println!("Example 9: RcConsumer composition (borrowing &self)");
println!("{}", "-".repeat(50));
let double = RcConsumer::new(|x: &i32| println!("double: {}", x * 2));
let add_ten = RcConsumer::new(|x: &i32| println!("add_ten: {}", x + 10));
let pipeline1 = double.and_then(add_ten.clone());
let pipeline2 = add_ten.and_then(double.clone());
let value1 = 5;
let p1 = pipeline1;
print!("pipeline1 processing 5: ");
p1.accept(&value1);
let value2 = 5;
let p2 = pipeline2;
print!("pipeline2 processing 5: ");
p2.accept(&value2);
println!();
println!("Example 10: Unified Consumer trait");
println!("{}", "-".repeat(50));
fn log_all<C: Consumer<i32>>(consumer: &mut C, values: &[i32]) {
for value in values.iter() {
consumer.accept(value);
}
}
let values = vec![1, 2, 3, 4, 5];
let mut box_con = BoxConsumer::new(|x: &i32| print!("{} ", x * 2));
print!("BoxConsumer processing {:?}: ", values);
log_all(&mut box_con, &values);
println!();
let mut arc_con = ArcConsumer::new(|x: &i32| print!("{} ", x * 2));
print!("ArcConsumer processing {:?}: ", values);
log_all(&mut arc_con, &values);
println!();
let mut rc_con = RcConsumer::new(|x: &i32| print!("{} ", x * 2));
print!("RcConsumer processing {:?}: ", values);
log_all(&mut rc_con, &values);
println!();
let mut closure = |x: &i32| print!("{} ", x * 2);
print!("Closure processing {:?}: ", values);
log_all(&mut closure, &values);
println!("\n");
println!("Example 11: Data validation and logging");
println!("{}", "-".repeat(50));
let validator = BoxConsumer::new(|x: &i32| {
let status = if *x >= 0 && *x <= 100 {
"valid"
} else {
"out of range"
};
println!("Validate {}: {}", x, status);
});
let logger = BoxConsumer::new(|x: &i32| {
println!("Log to file: value={}, square={}", x, x * x);
});
let pipeline = validator.and_then(logger);
let test_values = vec![-50, 30, 200];
for value in test_values {
pipeline.accept(&value);
}
println!();
println!("Example 12: String analysis");
println!("{}", "-".repeat(50));
let string_analyzer = BoxConsumer::new(|s: &String| {
println!("Length: {}", s.len());
})
.and_then(|s: &String| {
println!("Lowercase: {}", s.to_lowercase());
})
.and_then(|s: &String| {
println!("Uppercase: {}", s.to_uppercase());
})
.and_then(|s: &String| {
let word_count = s.split_whitespace().count();
println!("Word count: {}", word_count);
});
let text = String::from("Hello World");
println!("Analyzing text: \"{}\"", text);
string_analyzer.accept(&text);
println!("Original text: \"{}\" (not modified)\n", text);
println!("Example 13: Type conversion");
println!("{}", "-".repeat(50));
let closure = |x: &i32| print!("Processing: {} ", x * 2);
let box_con = Consumer::into_box(closure);
let value = 5;
print!("Closure -> BoxConsumer: ");
box_con.accept(&value);
println!();
let closure = |x: &i32| print!("Processing: {} ", x * 2);
let rc_con = Consumer::into_rc(closure);
let value = 5;
print!("Closure -> RcConsumer: ");
rc_con.accept(&value);
println!();
let closure = |x: &i32| print!("Processing: {} ", x * 2);
let arc_con = Consumer::into_arc(closure);
let value = 5;
print!("Closure -> ArcConsumer: ");
arc_con.accept(&value);
println!();
let box_con = BoxConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
let rc_con = box_con.into_rc();
let value = 5;
print!("BoxConsumer -> RcConsumer: ");
rc_con.accept(&value);
println!();
let rc_con = RcConsumer::new(|x: &i32| print!("Processing: {} ", x * 2));
let box_con = rc_con.into_box();
let value = 5;
print!("RcConsumer -> BoxConsumer: ");
box_con.accept(&value);
println!("\n");
println!("Example 14: Custom types");
println!("{}", "-".repeat(50));
#[derive(Debug, Clone)]
struct Point {
x: i32,
y: i32,
}
let analyzer = BoxConsumer::new(|p: &Point| {
println!("Point coordinates: ({}, {})", p.x, p.y);
})
.and_then(|p: &Point| {
let distance = ((p.x * p.x + p.y * p.y) as f64).sqrt();
println!("Distance from origin: {:.2}", distance);
})
.and_then(|p: &Point| {
let quadrant = match (p.x >= 0, p.y >= 0) {
(true, true) => "First quadrant",
(false, true) => "Second quadrant",
(false, false) => "Third quadrant",
(true, false) => "Fourth quadrant",
};
println!("Quadrant: {}", quadrant);
});
let point = Point { x: 3, y: 4 };
println!("Analyzing point: {:?}", point);
analyzer.accept(&point);
println!("Original point: {:?} (not modified)\n", point);
println!("Example 15: Data collection and statistics");
println!("{}", "-".repeat(50));
let sum = Arc::new(Mutex::new(0));
let count = Arc::new(Mutex::new(0));
let sum_clone = sum.clone();
let count_clone = count.clone();
let collector = BoxConsumer::new(move |x: &i32| {
*sum_clone.lock().unwrap() += *x;
*count_clone.lock().unwrap() += 1;
});
let numbers = vec![10, 20, 30, 40, 50];
println!("Numbers: {:?}", numbers);
for num in &numbers {
collector.accept(num);
}
let total = *sum.lock().unwrap();
let cnt = *count.lock().unwrap();
println!("Sum: {}", total);
println!("Count: {}", cnt);
println!("Average: {:.2}\n", total as f64 / cnt as f64);
println!("=== All examples completed ===");
println!("\nTip: For value modification functionality, please refer to mutator_demo.rs");
}