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