pub struct RcPredicate<T> { /* private fields */ }Expand description
An Rc-based predicate with single-threaded shared ownership.
This type is suitable for scenarios where the predicate needs to be
reused in a single-threaded context. Composition methods borrow &self,
allowing the original predicate to remain usable after composition.
§Examples
use prism3_function::predicate::{Predicate, RcPredicate};
let pred = RcPredicate::new(|x: &i32| *x > 0);
assert!(pred.test(&5));
// Original predicate remains usable after composition
let combined = pred.and(RcPredicate::new(|x| x % 2 == 0));
assert!(pred.test(&5)); // Still works§Author
Haixing Hu
Implementations§
Source§impl<T: 'static> RcPredicate<T>
impl<T: 'static> RcPredicate<T>
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new RcPredicate from a closure.
§Parameters
f- The closure to wrap.
§Returns
A new RcPredicate instance.
Examples found in repository?
37fn demo_with_vec_retain() {
38 println!("2. Using Vec::retain");
39
40 // RcPredicate example
41 let pred = RcPredicate::new(|x: &i32| *x % 2 == 0);
42 let mut numbers = vec![1, 2, 3, 4, 5, 6];
43 println!(" Original data: {:?}", numbers);
44 numbers.retain(pred.to_fn());
45 println!(" Retained even numbers: {:?}", numbers);
46 assert_eq!(numbers, vec![2, 4, 6]);
47
48 // Original predicate is still available
49 assert!(pred.test(&10));
50 println!(" ✓ RcPredicate::to_fn() can be used in retain");
51 println!(" ✓ Original predicate is still available\n");
52}
53
54/// Demonstrates usage with generic functions that require FnMut
55fn demo_with_generic_function() {
56 println!("3. Using generic functions (requires FnMut)");
57
58 fn count_matching<F>(items: &[i32], mut predicate: F) -> usize
59 where
60 F: FnMut(&i32) -> bool,
61 {
62 items.iter().filter(|x| predicate(x)).count()
63 }
64
65 let pred = RcPredicate::new(|x: &i32| *x > 10);
66 let count1 = count_matching(&[5, 15, 8, 20], pred.to_fn());
67 println!(" First call: count = {}", count1);
68 assert_eq!(count1, 2);
69
70 // Original predicate can be reused
71 let count2 = count_matching(&[12, 3, 18], pred.to_fn());
72 println!(" Second call: count = {}", count2);
73 assert_eq!(count2, 2);
74
75 println!(" ✓ RcPredicate::to_fn() can be passed to generic functions requiring FnMut");
76 println!(" ✓ Original predicate can be converted and used multiple times\n");
77}More examples
50fn demo_rc_predicate() {
51 println!("2. RcPredicate Naming Functionality");
52
53 // Using new_with_name
54 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
55 println!(" Using new_with_name:");
56 println!(" Name: {:?}", pred1.name());
57 println!(" Test 15: {}", pred1.test(&15));
58
59 // Using set_name
60 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
61 println!("\n Using set_name:");
62 println!(" Initial name: {:?}", pred2.name());
63 pred2.set_name("less_than_100");
64 println!(" Name after setting: {:?}", pred2.name());
65 println!(" Test 50: {}", pred2.test(&50));
66
67 // Name is preserved after cloning
68 let pred3 = pred2.clone();
69 println!("\n Name preserved after cloning:");
70 println!(" Cloned name: {:?}", pred3.name());
71 println!(" Test 80: {}\n", pred3.test(&80));
72}100fn 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 // Multiple compositions without consuming the original
107 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 // Cloning
125 let cloned = is_positive.clone();
126 println!("Cloned predicate: {}", cloned.test(&10));
127}
128
129/// ArcPredicate examples - multi-threaded scenarios
130fn 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 // Create combined predicate
137 let combined = is_positive.and(is_even);
138
139 // Use in multiple threads
140 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 // Original predicates still usable
155 println!("Original predicates still available in main thread:");
156 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
157}
158
159/// Logical composition examples
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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
213/// Interior mutability examples
214fn interior_mutability_examples() {
215 println!("--- 6. Interior Mutability Examples ---");
216
217 // BoxPredicate with counter (RefCell)
218 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 // Note: count is moved into the closure, so we can't access it here
228
229 // RcPredicate with cache (RefCell + HashMap)
230 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 // ArcPredicate with thread-safe counter (Mutex)
248 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
273/// Practical use cases
274fn practical_use_cases() {
275 println!("--- 7. Practical Use Cases ---");
276
277 // Validation rules
278 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 // Filter pipeline
313 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 // Strategy pattern
331 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}Sourcepub fn new_with_name<F>(name: &str, f: F) -> Self
pub fn new_with_name<F>(name: &str, f: F) -> Self
Creates a named RcPredicate from a closure.
§Parameters
name- The name for this predicate.f- The closure to wrap.
§Returns
A new named RcPredicate instance.
Examples found in repository?
50fn demo_rc_predicate() {
51 println!("2. RcPredicate Naming Functionality");
52
53 // Using new_with_name
54 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
55 println!(" Using new_with_name:");
56 println!(" Name: {:?}", pred1.name());
57 println!(" Test 15: {}", pred1.test(&15));
58
59 // Using set_name
60 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
61 println!("\n Using set_name:");
62 println!(" Initial name: {:?}", pred2.name());
63 pred2.set_name("less_than_100");
64 println!(" Name after setting: {:?}", pred2.name());
65 println!(" Test 50: {}", pred2.test(&50));
66
67 // Name is preserved after cloning
68 let pred3 = pred2.clone();
69 println!("\n Name preserved after cloning:");
70 println!(" Cloned name: {:?}", pred3.name());
71 println!(" Test 80: {}\n", pred3.test(&80));
72}More examples
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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
213/// Interior mutability examples
214fn interior_mutability_examples() {
215 println!("--- 6. Interior Mutability Examples ---");
216
217 // BoxPredicate with counter (RefCell)
218 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 // Note: count is moved into the closure, so we can't access it here
228
229 // RcPredicate with cache (RefCell + HashMap)
230 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 // ArcPredicate with thread-safe counter (Mutex)
248 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
273/// Practical use cases
274fn practical_use_cases() {
275 println!("--- 7. Practical Use Cases ---");
276
277 // Validation rules
278 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 // Filter pipeline
313 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 // Strategy pattern
331 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}Sourcepub fn always_true() -> Self
pub fn always_true() -> Self
Creates a predicate that always returns true.
§Returns
A new RcPredicate that always returns true.
§Examples
use prism3_function::predicate::{Predicate, RcPredicate};
let pred: RcPredicate<i32> = RcPredicate::always_true();
assert!(pred.test(&42));
assert!(pred.test(&-1));
assert!(pred.test(&0));Examples found in repository?
11fn main() {
12 println!("=== BoxPredicate always_true/always_false Demo ===\n");
13
14 // BoxPredicate::always_true
15 let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
16 println!("BoxPredicate::always_true():");
17 println!(" test(&42): {}", always_true.test(&42));
18 println!(" test(&-1): {}", always_true.test(&-1));
19 println!(" test(&0): {}", always_true.test(&0));
20 println!(" name: {:?}", always_true.name());
21
22 // BoxPredicate::always_false
23 let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
24 println!("\nBoxPredicate::always_false():");
25 println!(" test(&42): {}", always_false.test(&42));
26 println!(" test(&-1): {}", always_false.test(&-1));
27 println!(" test(&0): {}", always_false.test(&0));
28 println!(" name: {:?}", always_false.name());
29
30 println!("\n=== RcPredicate always_true/always_false Demo ===\n");
31
32 // RcPredicate::always_true
33 let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
34 println!("RcPredicate::always_true():");
35 println!(
36 " test(&\"hello\"): {}",
37 rc_always_true.test(&"hello".to_string())
38 );
39 println!(
40 " test(&\"world\"): {}",
41 rc_always_true.test(&"world".to_string())
42 );
43 println!(" name: {:?}", rc_always_true.name());
44
45 // RcPredicate::always_false
46 let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
47 println!("\nRcPredicate::always_false():");
48 println!(
49 " test(&\"hello\"): {}",
50 rc_always_false.test(&"hello".to_string())
51 );
52 println!(
53 " test(&\"world\"): {}",
54 rc_always_false.test(&"world".to_string())
55 );
56 println!(" name: {:?}", rc_always_false.name());
57
58 // Can be cloned and reused
59 let rc_clone = rc_always_true.clone();
60 println!("\nAfter cloning, still usable:");
61 println!(
62 " Original: test(&\"test\"): {}",
63 rc_always_true.test(&"test".to_string())
64 );
65 println!(
66 " Clone: test(&\"test\"): {}",
67 rc_clone.test(&"test".to_string())
68 );
69
70 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
71
72 // ArcPredicate::always_true
73 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
74 println!("ArcPredicate::always_true():");
75 println!(" test(&100): {}", arc_always_true.test(&100));
76 println!(" test(&-100): {}", arc_always_true.test(&-100));
77 println!(" name: {:?}", arc_always_true.name());
78
79 // ArcPredicate::always_false
80 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
81 println!("\nArcPredicate::always_false():");
82 println!(" test(&100): {}", arc_always_false.test(&100));
83 println!(" test(&-100): {}", arc_always_false.test(&-100));
84 println!(" name: {:?}", arc_always_false.name());
85
86 println!("\n=== Combining with other predicates ===\n");
87
88 // Combining with always_true (AND)
89 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
90 let combined_and_true = is_positive.and(BoxPredicate::always_true());
91 println!("is_positive AND always_true:");
92 println!(
93 " test(&5): {} (equivalent to is_positive)",
94 combined_and_true.test(&5)
95 );
96 println!(
97 " test(&-3): {} (equivalent to is_positive)",
98 combined_and_true.test(&-3)
99 );
100
101 // Combining with always_false (AND)
102 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
103 let combined_and_false = is_positive.and(BoxPredicate::always_false());
104 println!("\nis_positive AND always_false:");
105 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
106 println!(
107 " test(&-3): {} (always false)",
108 combined_and_false.test(&-3)
109 );
110
111 // Combining with always_true (OR)
112 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
113 let combined_or_true = is_positive.or(BoxPredicate::always_true());
114 println!("\nis_positive OR always_true:");
115 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
116 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
117
118 // Combining with always_false (OR)
119 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
120 let combined_or_false = is_positive.or(BoxPredicate::always_false());
121 println!("\nis_positive OR always_false:");
122 println!(
123 " test(&5): {} (equivalent to is_positive)",
124 combined_or_false.test(&5)
125 );
126 println!(
127 " test(&-3): {} (equivalent to is_positive)",
128 combined_or_false.test(&-3)
129 );
130
131 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
132
133 // Scenario 1: Default pass-all filter
134 let numbers = vec![1, 2, 3, 4, 5];
135 let pass_all = BoxPredicate::<i32>::always_true();
136 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
137 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
138
139 // Scenario 2: Default reject-all filter
140 let numbers = vec![1, 2, 3, 4, 5];
141 let reject_all = BoxPredicate::<i32>::always_false();
142 let filtered: Vec<_> = numbers
143 .iter()
144 .copied()
145 .filter(reject_all.into_fn())
146 .collect();
147 println!(
148 "Default reject all elements: {:?} -> {:?}",
149 numbers, filtered
150 );
151
152 // Scenario 3: Configurable filter
153 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
154 if enable_filter {
155 BoxPredicate::new(|x: &i32| *x > 3)
156 } else {
157 BoxPredicate::always_true()
158 }
159 }
160
161 let numbers = vec![1, 2, 3, 4, 5];
162
163 let filter_enabled = configurable_filter(true);
164 let filtered: Vec<_> = numbers
165 .iter()
166 .copied()
167 .filter(filter_enabled.into_fn())
168 .collect();
169 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
170
171 let filter_disabled = configurable_filter(false);
172 let filtered: Vec<_> = numbers
173 .iter()
174 .copied()
175 .filter(filter_disabled.into_fn())
176 .collect();
177 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
178}Sourcepub fn always_false() -> Self
pub fn always_false() -> Self
Creates a predicate that always returns false.
§Returns
A new RcPredicate that always returns false.
§Examples
use prism3_function::predicate::{Predicate, RcPredicate};
let pred: RcPredicate<i32> = RcPredicate::always_false();
assert!(!pred.test(&42));
assert!(!pred.test(&-1));
assert!(!pred.test(&0));Examples found in repository?
11fn main() {
12 println!("=== BoxPredicate always_true/always_false Demo ===\n");
13
14 // BoxPredicate::always_true
15 let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
16 println!("BoxPredicate::always_true():");
17 println!(" test(&42): {}", always_true.test(&42));
18 println!(" test(&-1): {}", always_true.test(&-1));
19 println!(" test(&0): {}", always_true.test(&0));
20 println!(" name: {:?}", always_true.name());
21
22 // BoxPredicate::always_false
23 let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
24 println!("\nBoxPredicate::always_false():");
25 println!(" test(&42): {}", always_false.test(&42));
26 println!(" test(&-1): {}", always_false.test(&-1));
27 println!(" test(&0): {}", always_false.test(&0));
28 println!(" name: {:?}", always_false.name());
29
30 println!("\n=== RcPredicate always_true/always_false Demo ===\n");
31
32 // RcPredicate::always_true
33 let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
34 println!("RcPredicate::always_true():");
35 println!(
36 " test(&\"hello\"): {}",
37 rc_always_true.test(&"hello".to_string())
38 );
39 println!(
40 " test(&\"world\"): {}",
41 rc_always_true.test(&"world".to_string())
42 );
43 println!(" name: {:?}", rc_always_true.name());
44
45 // RcPredicate::always_false
46 let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
47 println!("\nRcPredicate::always_false():");
48 println!(
49 " test(&\"hello\"): {}",
50 rc_always_false.test(&"hello".to_string())
51 );
52 println!(
53 " test(&\"world\"): {}",
54 rc_always_false.test(&"world".to_string())
55 );
56 println!(" name: {:?}", rc_always_false.name());
57
58 // Can be cloned and reused
59 let rc_clone = rc_always_true.clone();
60 println!("\nAfter cloning, still usable:");
61 println!(
62 " Original: test(&\"test\"): {}",
63 rc_always_true.test(&"test".to_string())
64 );
65 println!(
66 " Clone: test(&\"test\"): {}",
67 rc_clone.test(&"test".to_string())
68 );
69
70 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
71
72 // ArcPredicate::always_true
73 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
74 println!("ArcPredicate::always_true():");
75 println!(" test(&100): {}", arc_always_true.test(&100));
76 println!(" test(&-100): {}", arc_always_true.test(&-100));
77 println!(" name: {:?}", arc_always_true.name());
78
79 // ArcPredicate::always_false
80 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
81 println!("\nArcPredicate::always_false():");
82 println!(" test(&100): {}", arc_always_false.test(&100));
83 println!(" test(&-100): {}", arc_always_false.test(&-100));
84 println!(" name: {:?}", arc_always_false.name());
85
86 println!("\n=== Combining with other predicates ===\n");
87
88 // Combining with always_true (AND)
89 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
90 let combined_and_true = is_positive.and(BoxPredicate::always_true());
91 println!("is_positive AND always_true:");
92 println!(
93 " test(&5): {} (equivalent to is_positive)",
94 combined_and_true.test(&5)
95 );
96 println!(
97 " test(&-3): {} (equivalent to is_positive)",
98 combined_and_true.test(&-3)
99 );
100
101 // Combining with always_false (AND)
102 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
103 let combined_and_false = is_positive.and(BoxPredicate::always_false());
104 println!("\nis_positive AND always_false:");
105 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
106 println!(
107 " test(&-3): {} (always false)",
108 combined_and_false.test(&-3)
109 );
110
111 // Combining with always_true (OR)
112 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
113 let combined_or_true = is_positive.or(BoxPredicate::always_true());
114 println!("\nis_positive OR always_true:");
115 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
116 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
117
118 // Combining with always_false (OR)
119 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
120 let combined_or_false = is_positive.or(BoxPredicate::always_false());
121 println!("\nis_positive OR always_false:");
122 println!(
123 " test(&5): {} (equivalent to is_positive)",
124 combined_or_false.test(&5)
125 );
126 println!(
127 " test(&-3): {} (equivalent to is_positive)",
128 combined_or_false.test(&-3)
129 );
130
131 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
132
133 // Scenario 1: Default pass-all filter
134 let numbers = vec![1, 2, 3, 4, 5];
135 let pass_all = BoxPredicate::<i32>::always_true();
136 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
137 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
138
139 // Scenario 2: Default reject-all filter
140 let numbers = vec![1, 2, 3, 4, 5];
141 let reject_all = BoxPredicate::<i32>::always_false();
142 let filtered: Vec<_> = numbers
143 .iter()
144 .copied()
145 .filter(reject_all.into_fn())
146 .collect();
147 println!(
148 "Default reject all elements: {:?} -> {:?}",
149 numbers, filtered
150 );
151
152 // Scenario 3: Configurable filter
153 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
154 if enable_filter {
155 BoxPredicate::new(|x: &i32| *x > 3)
156 } else {
157 BoxPredicate::always_true()
158 }
159 }
160
161 let numbers = vec![1, 2, 3, 4, 5];
162
163 let filter_enabled = configurable_filter(true);
164 let filtered: Vec<_> = numbers
165 .iter()
166 .copied()
167 .filter(filter_enabled.into_fn())
168 .collect();
169 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
170
171 let filter_disabled = configurable_filter(false);
172 let filtered: Vec<_> = numbers
173 .iter()
174 .copied()
175 .filter(filter_disabled.into_fn())
176 .collect();
177 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
178}Sourcepub fn name(&self) -> Option<&str>
pub fn name(&self) -> Option<&str>
Examples found in repository?
50fn demo_rc_predicate() {
51 println!("2. RcPredicate Naming Functionality");
52
53 // Using new_with_name
54 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
55 println!(" Using new_with_name:");
56 println!(" Name: {:?}", pred1.name());
57 println!(" Test 15: {}", pred1.test(&15));
58
59 // Using set_name
60 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
61 println!("\n Using set_name:");
62 println!(" Initial name: {:?}", pred2.name());
63 pred2.set_name("less_than_100");
64 println!(" Name after setting: {:?}", pred2.name());
65 println!(" Test 50: {}", pred2.test(&50));
66
67 // Name is preserved after cloning
68 let pred3 = pred2.clone();
69 println!("\n Name preserved after cloning:");
70 println!(" Cloned name: {:?}", pred3.name());
71 println!(" Test 80: {}\n", pred3.test(&80));
72}More examples
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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}11fn main() {
12 println!("=== BoxPredicate always_true/always_false Demo ===\n");
13
14 // BoxPredicate::always_true
15 let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
16 println!("BoxPredicate::always_true():");
17 println!(" test(&42): {}", always_true.test(&42));
18 println!(" test(&-1): {}", always_true.test(&-1));
19 println!(" test(&0): {}", always_true.test(&0));
20 println!(" name: {:?}", always_true.name());
21
22 // BoxPredicate::always_false
23 let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
24 println!("\nBoxPredicate::always_false():");
25 println!(" test(&42): {}", always_false.test(&42));
26 println!(" test(&-1): {}", always_false.test(&-1));
27 println!(" test(&0): {}", always_false.test(&0));
28 println!(" name: {:?}", always_false.name());
29
30 println!("\n=== RcPredicate always_true/always_false Demo ===\n");
31
32 // RcPredicate::always_true
33 let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
34 println!("RcPredicate::always_true():");
35 println!(
36 " test(&\"hello\"): {}",
37 rc_always_true.test(&"hello".to_string())
38 );
39 println!(
40 " test(&\"world\"): {}",
41 rc_always_true.test(&"world".to_string())
42 );
43 println!(" name: {:?}", rc_always_true.name());
44
45 // RcPredicate::always_false
46 let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
47 println!("\nRcPredicate::always_false():");
48 println!(
49 " test(&\"hello\"): {}",
50 rc_always_false.test(&"hello".to_string())
51 );
52 println!(
53 " test(&\"world\"): {}",
54 rc_always_false.test(&"world".to_string())
55 );
56 println!(" name: {:?}", rc_always_false.name());
57
58 // Can be cloned and reused
59 let rc_clone = rc_always_true.clone();
60 println!("\nAfter cloning, still usable:");
61 println!(
62 " Original: test(&\"test\"): {}",
63 rc_always_true.test(&"test".to_string())
64 );
65 println!(
66 " Clone: test(&\"test\"): {}",
67 rc_clone.test(&"test".to_string())
68 );
69
70 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
71
72 // ArcPredicate::always_true
73 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
74 println!("ArcPredicate::always_true():");
75 println!(" test(&100): {}", arc_always_true.test(&100));
76 println!(" test(&-100): {}", arc_always_true.test(&-100));
77 println!(" name: {:?}", arc_always_true.name());
78
79 // ArcPredicate::always_false
80 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
81 println!("\nArcPredicate::always_false():");
82 println!(" test(&100): {}", arc_always_false.test(&100));
83 println!(" test(&-100): {}", arc_always_false.test(&-100));
84 println!(" name: {:?}", arc_always_false.name());
85
86 println!("\n=== Combining with other predicates ===\n");
87
88 // Combining with always_true (AND)
89 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
90 let combined_and_true = is_positive.and(BoxPredicate::always_true());
91 println!("is_positive AND always_true:");
92 println!(
93 " test(&5): {} (equivalent to is_positive)",
94 combined_and_true.test(&5)
95 );
96 println!(
97 " test(&-3): {} (equivalent to is_positive)",
98 combined_and_true.test(&-3)
99 );
100
101 // Combining with always_false (AND)
102 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
103 let combined_and_false = is_positive.and(BoxPredicate::always_false());
104 println!("\nis_positive AND always_false:");
105 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
106 println!(
107 " test(&-3): {} (always false)",
108 combined_and_false.test(&-3)
109 );
110
111 // Combining with always_true (OR)
112 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
113 let combined_or_true = is_positive.or(BoxPredicate::always_true());
114 println!("\nis_positive OR always_true:");
115 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
116 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
117
118 // Combining with always_false (OR)
119 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
120 let combined_or_false = is_positive.or(BoxPredicate::always_false());
121 println!("\nis_positive OR always_false:");
122 println!(
123 " test(&5): {} (equivalent to is_positive)",
124 combined_or_false.test(&5)
125 );
126 println!(
127 " test(&-3): {} (equivalent to is_positive)",
128 combined_or_false.test(&-3)
129 );
130
131 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
132
133 // Scenario 1: Default pass-all filter
134 let numbers = vec![1, 2, 3, 4, 5];
135 let pass_all = BoxPredicate::<i32>::always_true();
136 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
137 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
138
139 // Scenario 2: Default reject-all filter
140 let numbers = vec![1, 2, 3, 4, 5];
141 let reject_all = BoxPredicate::<i32>::always_false();
142 let filtered: Vec<_> = numbers
143 .iter()
144 .copied()
145 .filter(reject_all.into_fn())
146 .collect();
147 println!(
148 "Default reject all elements: {:?} -> {:?}",
149 numbers, filtered
150 );
151
152 // Scenario 3: Configurable filter
153 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
154 if enable_filter {
155 BoxPredicate::new(|x: &i32| *x > 3)
156 } else {
157 BoxPredicate::always_true()
158 }
159 }
160
161 let numbers = vec![1, 2, 3, 4, 5];
162
163 let filter_enabled = configurable_filter(true);
164 let filtered: Vec<_> = numbers
165 .iter()
166 .copied()
167 .filter(filter_enabled.into_fn())
168 .collect();
169 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
170
171 let filter_disabled = configurable_filter(false);
172 let filtered: Vec<_> = numbers
173 .iter()
174 .copied()
175 .filter(filter_disabled.into_fn())
176 .collect();
177 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
178}Sourcepub fn set_name(&mut self, name: &str)
pub fn set_name(&mut self, name: &str)
Examples found in repository?
50fn demo_rc_predicate() {
51 println!("2. RcPredicate Naming Functionality");
52
53 // Using new_with_name
54 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
55 println!(" Using new_with_name:");
56 println!(" Name: {:?}", pred1.name());
57 println!(" Test 15: {}", pred1.test(&15));
58
59 // Using set_name
60 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
61 println!("\n Using set_name:");
62 println!(" Initial name: {:?}", pred2.name());
63 pred2.set_name("less_than_100");
64 println!(" Name after setting: {:?}", pred2.name());
65 println!(" Test 50: {}", pred2.test(&50));
66
67 // Name is preserved after cloning
68 let pred3 = pred2.clone();
69 println!("\n Name preserved after cloning:");
70 println!(" Cloned name: {:?}", pred3.name());
71 println!(" Test 80: {}\n", pred3.test(&80));
72}Sourcepub fn and<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
pub fn and<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
Returns a predicate that represents the logical AND of this predicate and another.
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - Another
RcPredicate<T>(will be moved) - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new RcPredicate representing the logical AND.
§Examples
§Combining with closures (original predicate remains usable)
use prism3_function::predicate::{Predicate, RcPredicate};
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
// Note: is_positive is borrowed (&self), so it remains usable
let combined = is_positive.and(is_even);
assert!(combined.test(&4));
assert!(!combined.test(&3));
// original predicate remains usable because RcPredicate uses &self
assert!(is_positive.test(&5));§Combining with other RcPredicate (requires clone)
use prism3_function::predicate::{Predicate, RcPredicate};
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let is_even = RcPredicate::new(|x: &i32| x % 2 == 0);
// Note: is_even parameter is passed by value and will be moved
// If you need to continue using is_even, you should clone it
let combined = is_positive.and(is_even.clone());
assert!(combined.test(&4));
// both original predicates remain usable
assert!(is_positive.test(&5));
assert!(is_even.test(&6));§Reusing the same predicate multiple times
use prism3_function::predicate::{Predicate, RcPredicate};
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
// Note: is_positive is borrowed (&self), so it can be reused
let positive_and_even = is_positive.and(|x: &i32| x % 2 == 0);
let positive_and_small = is_positive.and(|x: &i32| *x < 100);
// is_positive can be combined multiple times because RcPredicate uses &self
assert!(positive_and_even.test(&4));
assert!(positive_and_small.test(&5));
assert!(is_positive.test(&10));Examples found in repository?
100fn 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 // Multiple compositions without consuming the original
107 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 // Cloning
125 let cloned = is_positive.clone();
126 println!("Cloned predicate: {}", cloned.test(&10));
127}
128
129/// ArcPredicate examples - multi-threaded scenarios
130fn 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 // Create combined predicate
137 let combined = is_positive.and(is_even);
138
139 // Use in multiple threads
140 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 // Original predicates still usable
155 println!("Original predicates still available in main thread:");
156 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
157}
158
159/// Logical composition examples
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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
213/// Interior mutability examples
214fn interior_mutability_examples() {
215 println!("--- 6. Interior Mutability Examples ---");
216
217 // BoxPredicate with counter (RefCell)
218 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 // Note: count is moved into the closure, so we can't access it here
228
229 // RcPredicate with cache (RefCell + HashMap)
230 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 // ArcPredicate with thread-safe counter (Mutex)
248 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
273/// Practical use cases
274fn practical_use_cases() {
275 println!("--- 7. Practical Use Cases ---");
276
277 // Validation rules
278 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 // Filter pipeline
313 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 // Strategy pattern
331 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}Sourcepub fn or<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
pub fn or<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
Returns a predicate that represents the logical OR of this predicate and another.
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - Another
RcPredicate<T>(will be moved) - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new RcPredicate representing the logical OR.
§Examples
use prism3_function::predicate::{Predicate, RcPredicate};
let is_negative = RcPredicate::new(|x: &i32| *x < 0);
let is_large = |x: &i32| *x > 100;
let combined = is_negative.or(is_large);
assert!(combined.test(&-5));
assert!(combined.test(&150));
assert!(!combined.test(&50));
// original predicate remains usable
assert!(is_negative.test(&-10));Examples found in repository?
100fn 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 // Multiple compositions without consuming the original
107 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 // Cloning
125 let cloned = is_positive.clone();
126 println!("Cloned predicate: {}", cloned.test(&10));
127}
128
129/// ArcPredicate examples - multi-threaded scenarios
130fn 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 // Create combined predicate
137 let combined = is_positive.and(is_even);
138
139 // Use in multiple threads
140 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 // Original predicates still usable
155 println!("Original predicates still available in main thread:");
156 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
157}
158
159/// Logical composition examples
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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}Sourcepub fn not(&self) -> RcPredicate<T>
pub fn not(&self) -> RcPredicate<T>
Returns a predicate that represents the logical negation of this predicate.
§Returns
A new RcPredicate representing the logical negation.
Examples found in repository?
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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}Sourcepub fn nand<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
pub fn nand<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
Returns a predicate that represents the logical NAND (NOT AND) of this predicate and another.
NAND returns true unless both predicates are true.
Equivalent to !(self AND other).
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - Another
RcPredicate<T>(will be moved) - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new RcPredicate representing the logical NAND.
§Examples
use prism3_function::predicate::{Predicate, RcPredicate};
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
let nand = is_positive.nand(is_even);
assert!(nand.test(&3)); // !(true && false) = true
assert!(!nand.test(&4)); // !(true && true) = false
// original predicate remains usable
assert!(is_positive.test(&5));Examples found in repository?
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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}Sourcepub fn xor<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
pub fn xor<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
Returns a predicate that represents the logical XOR (exclusive OR) of this predicate and another.
XOR returns true if exactly one of the predicates is true.
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - Another
RcPredicate<T>(will be moved) - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new RcPredicate representing the logical XOR.
§Examples
use prism3_function::predicate::{Predicate, RcPredicate};
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
let xor = is_positive.xor(is_even);
assert!(xor.test(&3)); // true ^ false = true
assert!(!xor.test(&4)); // true ^ true = false
assert!(!xor.test(&-1)); // false ^ false = false
// original predicate remains usable
assert!(is_positive.test(&5));Examples found in repository?
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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}Sourcepub fn nor<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
pub fn nor<P>(&self, other: P) -> RcPredicate<T>where
P: Predicate<T> + 'static,
Returns a predicate that represents the logical NOR (NOT OR) of this predicate and another.
NOR returns true only when both predicates are false. Equivalent
to !(self OR other).
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - Another
RcPredicate<T>(will be moved) - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new RcPredicate representing the logical NOR.
§Examples
use prism3_function::predicate::{Predicate, RcPredicate};
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
let nor = is_positive.nor(is_even);
assert!(nor.test(&-3)); // !(false || false) = true
assert!(!nor.test(&4)); // !(true || true) = false
assert!(!nor.test(&3)); // !(true || false) = false
// Original predicate remains usable
assert!(is_positive.test(&5));Examples found in repository?
160fn 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 // AND composition
168 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 // OR composition
174 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 // NOT composition
180 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 // NAND composition
186 let nand = positive.nand(even.clone());
187 println!("positive NAND even: name={:?}", nand.name());
188 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
189 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
190
191 // XOR composition
192 let xor = positive.xor(even.clone());
193 println!("positive XOR even: name={:?}", xor.name());
194 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
195 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
196 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
197
198 // NOR composition
199 let nor = positive.nor(even.clone());
200 println!("positive NOR even: name={:?}", nor.name());
201 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
202 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
203 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
204 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
205
206 // Complex composition
207 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}Trait Implementations§
Source§impl<T> Clone for RcPredicate<T>
impl<T> Clone for RcPredicate<T>
Source§impl<T> Debug for RcPredicate<T>
impl<T> Debug for RcPredicate<T>
Source§impl<T> Display for RcPredicate<T>
impl<T> Display for RcPredicate<T>
Source§impl<T: 'static> Predicate<T> for RcPredicate<T>
impl<T: 'static> Predicate<T> for RcPredicate<T>
Source§fn test(&self, value: &T) -> bool
fn test(&self, value: &T) -> bool
Source§fn into_box(self) -> BoxPredicate<T>
fn into_box(self) -> BoxPredicate<T>
BoxPredicate. Read moreSource§fn into_rc(self) -> RcPredicate<T>
fn into_rc(self) -> RcPredicate<T>
RcPredicate. Read moreSource§fn into_fn(self) -> impl Fn(&T) -> bool
fn into_fn(self) -> impl Fn(&T) -> bool
Source§fn to_box(&self) -> BoxPredicate<T>
fn to_box(&self) -> BoxPredicate<T>
BoxPredicate. Read moreSource§fn to_rc(&self) -> RcPredicate<T>
fn to_rc(&self) -> RcPredicate<T>
RcPredicate. Read moreSource§fn to_fn(&self) -> impl Fn(&T) -> bool
fn to_fn(&self) -> impl Fn(&T) -> bool
Source§fn into_arc(self) -> ArcPredicate<T>
fn into_arc(self) -> ArcPredicate<T>
ArcPredicate. Read more