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