use qubit_function::{
ArcPredicate,
BoxPredicate,
Predicate,
RcPredicate,
};
fn main() {
println!("=== Demonstrating Predicate interop with FnMut ===\n");
demo_with_iterator_filter();
demo_with_vec_retain();
demo_with_generic_function();
demo_thread_safe();
}
fn demo_with_iterator_filter() {
println!("1. Using Iterator::filter");
let pred = BoxPredicate::new(|x: &i32| *x > 0);
let numbers = vec![-2, -1, 0, 1, 2, 3];
let positives: Vec<_> = numbers
.iter()
.copied()
.filter(|value| pred.test(value))
.collect();
println!(" Original data: {:?}", numbers);
println!(" Filtered result: {:?}", positives);
assert_eq!(positives, vec![1, 2, 3]);
println!(" ✓ BoxPredicate can be adapted for filter\n");
}
fn demo_with_vec_retain() {
println!("2. Using Vec::retain");
let pred = RcPredicate::new(|x: &i32| *x % 2 == 0);
let mut numbers = vec![1, 2, 3, 4, 5, 6];
println!(" Original data: {:?}", numbers);
numbers.retain(|value| pred.test(value));
println!(" Retained even numbers: {:?}", numbers);
assert_eq!(numbers, vec![2, 4, 6]);
assert!(pred.test(&10));
println!(" ✓ RcPredicate can be adapted for retain");
println!(" ✓ Original predicate is still available\n");
}
fn demo_with_generic_function() {
println!("3. Using generic functions (requires FnMut)");
fn count_matching<F>(items: &[i32], mut predicate: F) -> usize
where
F: FnMut(&i32) -> bool,
{
items.iter().filter(|x| predicate(x)).count()
}
let pred = RcPredicate::new(|x: &i32| *x > 10);
let count1 = count_matching(&[5, 15, 8, 20], |value| pred.test(value));
println!(" First call: count = {}", count1);
assert_eq!(count1, 2);
let count2 = count_matching(&[12, 3, 18], |value| pred.test(value));
println!(" Second call: count = {}", count2);
assert_eq!(count2, 2);
println!(" ✓ RcPredicate can be passed through a forwarding closure");
println!(" ✓ Original predicate remains reusable\n");
}
fn demo_thread_safe() {
println!("4. Thread-safe usage");
let pred = ArcPredicate::new(|x: &i32| *x > 0);
let thread_pred = pred.clone();
let closure = move |value: &i32| thread_pred.test(value);
let handle = std::thread::spawn(move || {
let numbers = [-2, -1, 0, 1, 2, 3];
numbers.iter().copied().filter(closure).count()
});
let count = handle.join().expect("thread should not panic");
println!(" Filtered result count in thread: {}", count);
assert_eq!(count, 3);
assert!(pred.test(&5));
println!(" ✓ ArcPredicate can be adapted to a thread-safe closure");
println!(" ✓ Original predicate is still available in main thread\n");
}