1use qubit_function::{
23 ArcPredicate,
24 BoxPredicate,
25 FnPredicateOps,
26 Predicate,
27 RcPredicate,
28};
29use std::cell::RefCell;
30use std::collections::HashMap;
31use std::sync::{
32 Arc,
33 Mutex,
34};
35
36fn main() {
37 println!("=== Predicate Usage Examples ===\n");
38
39 basic_closure_predicates();
40 println!();
41
42 box_predicate_examples();
43 println!();
44
45 rc_predicate_examples();
46 println!();
47
48 arc_predicate_examples();
49 println!();
50
51 logical_composition_examples();
52 println!();
53
54 interior_mutability_examples();
55 println!();
56
57 practical_use_cases();
58}
59
60fn basic_closure_predicates() {
62 println!("--- 1. Basic Closure Predicate Usage ---");
63
64 let is_positive = |x: &i32| *x > 0;
66 println!("Is 5 positive? {}", is_positive.test(&5));
67 println!("Is -3 positive? {}", is_positive.test(&-3));
68
69 let is_even = |x: &i32| x % 2 == 0;
71 let is_positive_and_even = is_positive.and(is_even);
72 println!("Is 4 positive and even? {}", is_positive_and_even.test(&4));
73 println!("Is 5 positive and even? {}", is_positive_and_even.test(&5));
74
75 let numbers = [-2, -1, 0, 1, 2, 3, 4, 5];
77 let positives: Vec<_> = numbers
78 .iter()
79 .filter(|x| is_positive.test(x))
80 .copied()
81 .collect();
82 println!("Positive numbers: {:?}", positives);
83}
84
85fn box_predicate_examples() {
87 println!("--- 2. BoxPredicate Examples (Single Ownership) ---");
88
89 let pred = BoxPredicate::new(|x: &i32| *x > 0);
91 println!("BoxPredicate test 5: {}", pred.test(&5));
92
93 let named_pred =
95 BoxPredicate::new_with_name("is_positive_even", |x: &i32| *x > 0 && x % 2 == 0);
96 println!("Predicate name: {:?}", named_pred.name());
97 println!("Test 4: {}", named_pred.test(&4));
98
99 let positive = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
101 let even = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
102 let combined = positive.and(even);
103 println!("Combined predicate name: {:?}", combined.name());
104 println!("Test 4: {}", combined.test(&4));
105}
106
107fn rc_predicate_examples() {
109 println!("--- 3. RcPredicate Examples (Single-threaded Reuse) ---");
110
111 let is_positive = RcPredicate::new(|x: &i32| *x > 0);
112 let is_even = RcPredicate::new(|x: &i32| x % 2 == 0);
113
114 let positive_and_even = is_positive.and(is_even.clone());
116 let positive_or_even = is_positive.or(is_even.clone());
117
118 println!("Original predicates still available:");
119 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
120 println!(" is_even.test(&4) = {}", is_even.test(&4));
121
122 println!("Combined predicates:");
123 println!(
124 " positive_and_even.test(&4) = {}",
125 positive_and_even.test(&4)
126 );
127 println!(
128 " positive_or_even.test(&5) = {}",
129 positive_or_even.test(&5)
130 );
131
132 let cloned = is_positive.clone();
134 println!("Cloned predicate: {}", cloned.test(&10));
135}
136
137fn arc_predicate_examples() {
139 println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
140
141 let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
142 let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
143
144 let combined = is_positive.and(is_even);
146
147 let handles: Vec<_> = (0..3)
149 .map(|i| {
150 let pred = combined.clone();
151 std::thread::spawn(move || {
152 let value = i * 2;
153 println!(" Thread {} testing {}: {}", i, value, pred.test(&value));
154 })
155 })
156 .collect();
157
158 for handle in handles {
159 handle.join().unwrap();
160 }
161
162 println!("Original predicates still available in main thread:");
164 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
165}
166
167fn logical_composition_examples() {
169 println!("--- 5. Logical Composition Examples ---");
170
171 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
172 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
173 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
174
175 let positive_and_even = positive.and(even.clone());
177 println!("positive AND even: name={:?}", positive_and_even.name());
178 println!(" Test 4: {}", positive_and_even.test(&4));
179 println!(" Test 5: {}", positive_and_even.test(&5));
180
181 let positive_or_even = positive.or(even.clone());
183 println!("positive OR even: name={:?}", positive_or_even.name());
184 println!(" Test -2: {}", positive_or_even.test(&-2));
185 println!(" Test 5: {}", positive_or_even.test(&5));
186
187 let not_positive = positive.not();
189 println!("NOT positive: name={:?}", not_positive.name());
190 println!(" Test 5: {}", not_positive.test(&5));
191 println!(" Test -3: {}", not_positive.test(&-3));
192
193 let nand = positive.nand(even.clone());
195 println!("positive NAND even: name={:?}", nand.name());
196 println!(" Test 3: {}", nand.test(&3)); println!(" Test 4: {}", nand.test(&4)); let xor = positive.xor(even.clone());
201 println!("positive XOR even: name={:?}", xor.name());
202 println!(" Test 3: {}", xor.test(&3)); println!(" Test 4: {}", xor.test(&4)); println!(" Test -2: {}", xor.test(&-2)); let nor = positive.nor(even.clone());
208 println!("positive NOR even: name={:?}", nor.name());
209 println!(" Test -3: {}", nor.test(&-3)); println!(" Test 3: {}", nor.test(&3)); println!(" Test -2: {}", nor.test(&-2)); println!(" Test 4: {}", nor.test(&4)); let complex = positive.and(even.clone()).and(less_than_ten.clone());
216 println!("Complex composition: name={:?}", complex.name());
217 println!(" Test 4: {}", complex.test(&4));
218 println!(" Test 12: {}", complex.test(&12));
219}
220
221fn interior_mutability_examples() {
223 println!("--- 6. Interior Mutability Examples ---");
224
225 println!("BoxPredicate with counter:");
227 let count = RefCell::new(0);
228 let pred = BoxPredicate::new(move |x: &i32| {
229 *count.borrow_mut() += 1;
230 *x > 0
231 });
232 println!(" Test 5: {}", pred.test(&5));
233 println!(" Test -3: {}", pred.test(&-3));
234 println!(" Test 10: {}", pred.test(&10));
235 println!("\nRcPredicate with cache:");
239 let cache: RefCell<HashMap<i32, bool>> = RefCell::new(HashMap::new());
240 let expensive_pred = RcPredicate::new(move |x: &i32| {
241 let mut c = cache.borrow_mut();
242 *c.entry(*x).or_insert_with(|| {
243 println!(" Computing result for {} (expensive operation)", x);
244 *x > 0 && x % 2 == 0
245 })
246 });
247
248 println!(" First test 4:");
249 println!(" Result: {}", expensive_pred.test(&4));
250 println!(" Test 4 again (using cache):");
251 println!(" Result: {}", expensive_pred.test(&4));
252 println!(" Test 3:");
253 println!(" Result: {}", expensive_pred.test(&3));
254
255 println!("\nArcPredicate with thread-safe counter:");
257 let counter = Arc::new(Mutex::new(0));
258 let pred = ArcPredicate::new({
259 let counter = Arc::clone(&counter);
260 move |x: &i32| {
261 let mut c = counter.lock().unwrap();
262 *c += 1;
263 *x > 0
264 }
265 });
266
267 let pred_clone = pred.clone();
268 let counter_clone = Arc::clone(&counter);
269
270 let handle = std::thread::spawn(move || {
271 pred_clone.test(&5);
272 pred_clone.test(&10);
273 });
274
275 pred.test(&3);
276 handle.join().unwrap();
277
278 println!(" Total call count: {}", counter_clone.lock().unwrap());
279}
280
281fn practical_use_cases() {
283 println!("--- 7. Practical Use Cases ---");
284
285 println!("Scenario 1: Form Validation");
287 struct User {
288 name: String,
289 age: i32,
290 email: String,
291 }
292
293 let name_valid =
294 RcPredicate::new_with_name("name_not_empty", |user: &User| !user.name.is_empty());
295
296 let age_valid = RcPredicate::new_with_name("age_between_18_120", |user: &User| {
297 user.age >= 18 && user.age <= 120
298 });
299
300 let email_valid =
301 RcPredicate::new_with_name("email_contains_at", |user: &User| user.email.contains('@'));
302
303 let all_valid = name_valid.and(age_valid.clone()).and(email_valid.clone());
304
305 let user1 = User {
306 name: "Alice".to_string(),
307 age: 25,
308 email: "alice@example.com".to_string(),
309 };
310
311 let user2 = User {
312 name: "".to_string(),
313 age: 25,
314 email: "bob@example.com".to_string(),
315 };
316
317 println!(" user1 validation: {}", all_valid.test(&user1));
318 println!(" user2 validation: {}", all_valid.test(&user2));
319
320 println!("\nScenario 2: Data Filtering Pipeline");
322 let numbers: Vec<i32> = (-10..=10).collect();
323
324 let positive = |x: &i32| *x > 0;
325 let even = |x: &i32| x % 2 == 0;
326 let less_than_eight = |x: &i32| *x < 8;
327
328 let filtered: Vec<i32> = numbers
329 .iter()
330 .filter(|x| positive.test(x))
331 .filter(|x| even.test(x))
332 .filter(|x| less_than_eight.test(x))
333 .copied()
334 .collect();
335
336 println!(" Filtered numbers: {:?}", filtered);
337
338 println!("\nScenario 3: Strategy Pattern");
340 let mut strategies: HashMap<&str, RcPredicate<i32>> = HashMap::new();
341 strategies.insert("positive", RcPredicate::new(|x: &i32| *x > 0));
342 strategies.insert("negative", RcPredicate::new(|x: &i32| *x < 0));
343 strategies.insert("even", RcPredicate::new(|x: &i32| x % 2 == 0));
344
345 let test_value = 4;
346 for (name, pred) in strategies.iter() {
347 println!(
348 " {} strategy test {}: {}",
349 name,
350 test_value,
351 pred.test(&test_value)
352 );
353 }
354}