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 qubit_function::{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 worksImplementations§
Source§impl<T> RcPredicate<T>
impl<T> RcPredicate<T>
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new predicate.
Wraps the provided closure in the appropriate smart pointer type for this predicate implementation.
Examples found in repository?
43fn demo_with_vec_retain() {
44 println!("2. Using Vec::retain");
45
46 // RcPredicate example
47 let pred = RcPredicate::new(|x: &i32| *x % 2 == 0);
48 let mut numbers = vec![1, 2, 3, 4, 5, 6];
49 println!(" Original data: {:?}", numbers);
50 numbers.retain(pred.to_fn());
51 println!(" Retained even numbers: {:?}", numbers);
52 assert_eq!(numbers, vec![2, 4, 6]);
53
54 // Original predicate is still available
55 assert!(pred.test(&10));
56 println!(" ✓ RcPredicate::to_fn() can be used in retain");
57 println!(" ✓ Original predicate is still available\n");
58}
59
60/// Demonstrates usage with generic functions that require FnMut
61fn demo_with_generic_function() {
62 println!("3. Using generic functions (requires FnMut)");
63
64 fn count_matching<F>(items: &[i32], mut predicate: F) -> usize
65 where
66 F: FnMut(&i32) -> bool,
67 {
68 items.iter().filter(|x| predicate(x)).count()
69 }
70
71 let pred = RcPredicate::new(|x: &i32| *x > 10);
72 let count1 = count_matching(&[5, 15, 8, 20], pred.to_fn());
73 println!(" First call: count = {}", count1);
74 assert_eq!(count1, 2);
75
76 // Original predicate can be reused
77 let count2 = count_matching(&[12, 3, 18], pred.to_fn());
78 println!(" Second call: count = {}", count2);
79 assert_eq!(count2, 2);
80
81 println!(" ✓ RcPredicate::to_fn() can be passed to generic functions requiring FnMut");
82 println!(" ✓ Original predicate can be converted and used multiple times\n");
83}More examples
56fn demo_rc_predicate() {
57 println!("2. RcPredicate Naming Functionality");
58
59 // Using new_with_name
60 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
61 println!(" Using new_with_name:");
62 println!(" Name: {:?}", pred1.name());
63 println!(" Test 15: {}", pred1.test(&15));
64
65 // Using set_name
66 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
67 println!("\n Using set_name:");
68 println!(" Initial name: {:?}", pred2.name());
69 pred2.set_name("less_than_100");
70 println!(" Name after setting: {:?}", pred2.name());
71 println!(" Test 50: {}", pred2.test(&50));
72
73 // Name is preserved after cloning
74 let pred3 = pred2.clone();
75 println!("\n Name preserved after cloning:");
76 println!(" Cloned name: {:?}", pred3.name());
77 println!(" Test 80: {}\n", pred3.test(&80));
78}103fn rc_predicate_examples() {
104 println!("--- 3. RcPredicate Examples (Single-threaded Reuse) ---");
105
106 let is_positive = RcPredicate::new(|x: &i32| *x > 0);
107 let is_even = RcPredicate::new(|x: &i32| x % 2 == 0);
108
109 // Multiple compositions without consuming the original
110 let positive_and_even = is_positive.and(is_even.clone());
111 let positive_or_even = is_positive.or(is_even.clone());
112
113 println!("Original predicates still available:");
114 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
115 println!(" is_even.test(&4) = {}", is_even.test(&4));
116
117 println!("Combined predicates:");
118 println!(" positive_and_even.test(&4) = {}", positive_and_even.test(&4));
119 println!(" positive_or_even.test(&5) = {}", positive_or_even.test(&5));
120
121 // Cloning
122 let cloned = is_positive.clone();
123 println!("Cloned predicate: {}", cloned.test(&10));
124}
125
126/// ArcPredicate examples - multi-threaded scenarios
127fn arc_predicate_examples() {
128 println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
129
130 let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
131 let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
132
133 // Create combined predicate
134 let combined = is_positive.and(is_even);
135
136 // Use in multiple threads
137 let handles: Vec<_> = (0..3)
138 .map(|i| {
139 let pred = combined.clone();
140 std::thread::spawn(move || {
141 let value = i * 2;
142 println!(" Thread {} testing {}: {}", i, value, pred.test(&value));
143 })
144 })
145 .collect();
146
147 for handle in handles {
148 handle.join().expect("thread should not panic");
149 }
150
151 // Original predicates still usable
152 println!("Original predicates still available in main thread:");
153 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
154}
155
156/// Logical composition examples
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}
209
210/// Interior mutability examples
211fn interior_mutability_examples() {
212 println!("--- 6. Interior Mutability Examples ---");
213
214 // BoxPredicate with counter (RefCell)
215 println!("BoxPredicate with counter:");
216 let count = RefCell::new(0);
217 let pred = BoxPredicate::new(move |x: &i32| {
218 *count.borrow_mut() += 1;
219 *x > 0
220 });
221 println!(" Test 5: {}", pred.test(&5));
222 println!(" Test -3: {}", pred.test(&-3));
223 println!(" Test 10: {}", pred.test(&10));
224 // Note: count is moved into the closure, so we can't access it here
225
226 // RcPredicate with cache (RefCell + HashMap)
227 println!("\nRcPredicate with cache:");
228 let cache: RefCell<HashMap<i32, bool>> = RefCell::new(HashMap::new());
229 let expensive_pred = RcPredicate::new(move |x: &i32| {
230 let mut c = cache.borrow_mut();
231 *c.entry(*x).or_insert_with(|| {
232 println!(" Computing result for {} (expensive operation)", x);
233 *x > 0 && x % 2 == 0
234 })
235 });
236
237 println!(" First test 4:");
238 println!(" Result: {}", expensive_pred.test(&4));
239 println!(" Test 4 again (using cache):");
240 println!(" Result: {}", expensive_pred.test(&4));
241 println!(" Test 3:");
242 println!(" Result: {}", expensive_pred.test(&3));
243
244 // ArcPredicate with thread-safe counter (Mutex)
245 println!("\nArcPredicate with thread-safe counter:");
246 let counter = Arc::new(Mutex::new(0));
247 let pred = ArcPredicate::new({
248 let counter = Arc::clone(&counter);
249 move |x: &i32| {
250 let mut c = counter.lock().expect("mutex should not be poisoned");
251 *c += 1;
252 *x > 0
253 }
254 });
255
256 let pred_clone = pred.clone();
257 let counter_clone = Arc::clone(&counter);
258
259 let handle = std::thread::spawn(move || {
260 pred_clone.test(&5);
261 pred_clone.test(&10);
262 });
263
264 pred.test(&3);
265 handle.join().expect("thread should not panic");
266
267 println!(
268 " Total call count: {}",
269 counter_clone.lock().expect("mutex should not be poisoned")
270 );
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 = RcPredicate::new_with_name("name_not_empty", |user: &User| !user.name.is_empty());
286
287 let age_valid = RcPredicate::new_with_name("age_between_18_120", |user: &User| user.age >= 18 && user.age <= 120);
288
289 let email_valid = RcPredicate::new_with_name("email_contains_at", |user: &User| user.email.contains('@'));
290
291 let all_valid = name_valid.and(age_valid.clone()).and(email_valid.clone());
292
293 let user1 = User {
294 name: "Alice".to_string(),
295 age: 25,
296 email: "alice@example.com".to_string(),
297 };
298
299 let user2 = User {
300 name: "".to_string(),
301 age: 25,
302 email: "bob@example.com".to_string(),
303 };
304
305 println!(" user1 validation: {}", all_valid.test(&user1));
306 println!(" user2 validation: {}", all_valid.test(&user2));
307
308 // Filter pipeline
309 println!("\nScenario 2: Data Filtering Pipeline");
310 let numbers: Vec<i32> = (-10..=10).collect();
311
312 let positive = |x: &i32| *x > 0;
313 let even = |x: &i32| x % 2 == 0;
314 let less_than_eight = |x: &i32| *x < 8;
315
316 let filtered: Vec<i32> = numbers
317 .iter()
318 .filter(|x| positive.test(x))
319 .filter(|x| even.test(x))
320 .filter(|x| less_than_eight.test(x))
321 .copied()
322 .collect();
323
324 println!(" Filtered numbers: {:?}", filtered);
325
326 // Strategy pattern
327 println!("\nScenario 3: Strategy Pattern");
328 let mut strategies: HashMap<&str, RcPredicate<i32>> = HashMap::new();
329 strategies.insert("positive", RcPredicate::new(|x: &i32| *x > 0));
330 strategies.insert("negative", RcPredicate::new(|x: &i32| *x < 0));
331 strategies.insert("even", RcPredicate::new(|x: &i32| x % 2 == 0));
332
333 let test_value = 4;
334 for (name, pred) in strategies.iter() {
335 println!(" {} strategy test {}: {}", name, test_value, pred.test(&test_value));
336 }
337}Sourcepub fn new_with_name<F>(name: &str, f: F) -> Self
pub fn new_with_name<F>(name: &str, f: F) -> Self
Creates a new named predicate.
Wraps the provided closure and assigns it a name, which is useful for debugging and logging purposes.
Examples found in repository?
56fn demo_rc_predicate() {
57 println!("2. RcPredicate Naming Functionality");
58
59 // Using new_with_name
60 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
61 println!(" Using new_with_name:");
62 println!(" Name: {:?}", pred1.name());
63 println!(" Test 15: {}", pred1.test(&15));
64
65 // Using set_name
66 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
67 println!("\n Using set_name:");
68 println!(" Initial name: {:?}", pred2.name());
69 pred2.set_name("less_than_100");
70 println!(" Name after setting: {:?}", pred2.name());
71 println!(" Test 50: {}", pred2.test(&50));
72
73 // Name is preserved after cloning
74 let pred3 = pred2.clone();
75 println!("\n Name preserved after cloning:");
76 println!(" Cloned name: {:?}", pred3.name());
77 println!(" Test 80: {}\n", pred3.test(&80));
78}More examples
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}
209
210/// Interior mutability examples
211fn interior_mutability_examples() {
212 println!("--- 6. Interior Mutability Examples ---");
213
214 // BoxPredicate with counter (RefCell)
215 println!("BoxPredicate with counter:");
216 let count = RefCell::new(0);
217 let pred = BoxPredicate::new(move |x: &i32| {
218 *count.borrow_mut() += 1;
219 *x > 0
220 });
221 println!(" Test 5: {}", pred.test(&5));
222 println!(" Test -3: {}", pred.test(&-3));
223 println!(" Test 10: {}", pred.test(&10));
224 // Note: count is moved into the closure, so we can't access it here
225
226 // RcPredicate with cache (RefCell + HashMap)
227 println!("\nRcPredicate with cache:");
228 let cache: RefCell<HashMap<i32, bool>> = RefCell::new(HashMap::new());
229 let expensive_pred = RcPredicate::new(move |x: &i32| {
230 let mut c = cache.borrow_mut();
231 *c.entry(*x).or_insert_with(|| {
232 println!(" Computing result for {} (expensive operation)", x);
233 *x > 0 && x % 2 == 0
234 })
235 });
236
237 println!(" First test 4:");
238 println!(" Result: {}", expensive_pred.test(&4));
239 println!(" Test 4 again (using cache):");
240 println!(" Result: {}", expensive_pred.test(&4));
241 println!(" Test 3:");
242 println!(" Result: {}", expensive_pred.test(&3));
243
244 // ArcPredicate with thread-safe counter (Mutex)
245 println!("\nArcPredicate with thread-safe counter:");
246 let counter = Arc::new(Mutex::new(0));
247 let pred = ArcPredicate::new({
248 let counter = Arc::clone(&counter);
249 move |x: &i32| {
250 let mut c = counter.lock().expect("mutex should not be poisoned");
251 *c += 1;
252 *x > 0
253 }
254 });
255
256 let pred_clone = pred.clone();
257 let counter_clone = Arc::clone(&counter);
258
259 let handle = std::thread::spawn(move || {
260 pred_clone.test(&5);
261 pred_clone.test(&10);
262 });
263
264 pred.test(&3);
265 handle.join().expect("thread should not panic");
266
267 println!(
268 " Total call count: {}",
269 counter_clone.lock().expect("mutex should not be poisoned")
270 );
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 = RcPredicate::new_with_name("name_not_empty", |user: &User| !user.name.is_empty());
286
287 let age_valid = RcPredicate::new_with_name("age_between_18_120", |user: &User| user.age >= 18 && user.age <= 120);
288
289 let email_valid = RcPredicate::new_with_name("email_contains_at", |user: &User| user.email.contains('@'));
290
291 let all_valid = name_valid.and(age_valid.clone()).and(email_valid.clone());
292
293 let user1 = User {
294 name: "Alice".to_string(),
295 age: 25,
296 email: "alice@example.com".to_string(),
297 };
298
299 let user2 = User {
300 name: "".to_string(),
301 age: 25,
302 email: "bob@example.com".to_string(),
303 };
304
305 println!(" user1 validation: {}", all_valid.test(&user1));
306 println!(" user2 validation: {}", all_valid.test(&user2));
307
308 // Filter pipeline
309 println!("\nScenario 2: Data Filtering Pipeline");
310 let numbers: Vec<i32> = (-10..=10).collect();
311
312 let positive = |x: &i32| *x > 0;
313 let even = |x: &i32| x % 2 == 0;
314 let less_than_eight = |x: &i32| *x < 8;
315
316 let filtered: Vec<i32> = numbers
317 .iter()
318 .filter(|x| positive.test(x))
319 .filter(|x| even.test(x))
320 .filter(|x| less_than_eight.test(x))
321 .copied()
322 .collect();
323
324 println!(" Filtered numbers: {:?}", filtered);
325
326 // Strategy pattern
327 println!("\nScenario 3: Strategy Pattern");
328 let mut strategies: HashMap<&str, RcPredicate<i32>> = HashMap::new();
329 strategies.insert("positive", RcPredicate::new(|x: &i32| *x > 0));
330 strategies.insert("negative", RcPredicate::new(|x: &i32| *x < 0));
331 strategies.insert("even", RcPredicate::new(|x: &i32| x % 2 == 0));
332
333 let test_value = 4;
334 for (name, pred) in strategies.iter() {
335 println!(" {} strategy test {}: {}", name, test_value, pred.test(&test_value));
336 }
337}Sourcepub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
pub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
Creates a new named predicate with an optional name.
Wraps the provided closure and assigns it an optional name.
Sourcepub fn name(&self) -> Option<&str>
pub fn name(&self) -> Option<&str>
Examples found in repository?
56fn demo_rc_predicate() {
57 println!("2. RcPredicate Naming Functionality");
58
59 // Using new_with_name
60 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
61 println!(" Using new_with_name:");
62 println!(" Name: {:?}", pred1.name());
63 println!(" Test 15: {}", pred1.test(&15));
64
65 // Using set_name
66 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
67 println!("\n Using set_name:");
68 println!(" Initial name: {:?}", pred2.name());
69 pred2.set_name("less_than_100");
70 println!(" Name after setting: {:?}", pred2.name());
71 println!(" Test 50: {}", pred2.test(&50));
72
73 // Name is preserved after cloning
74 let pred3 = pred2.clone();
75 println!("\n Name preserved after cloning:");
76 println!(" Cloned name: {:?}", pred3.name());
77 println!(" Test 80: {}\n", pred3.test(&80));
78}More examples
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}17fn main() {
18 println!("=== BoxPredicate always_true/always_false Demo ===\n");
19
20 // BoxPredicate::always_true
21 let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
22 println!("BoxPredicate::always_true():");
23 println!(" test(&42): {}", always_true.test(&42));
24 println!(" test(&-1): {}", always_true.test(&-1));
25 println!(" test(&0): {}", always_true.test(&0));
26 println!(" name: {:?}", always_true.name());
27
28 // BoxPredicate::always_false
29 let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
30 println!("\nBoxPredicate::always_false():");
31 println!(" test(&42): {}", always_false.test(&42));
32 println!(" test(&-1): {}", always_false.test(&-1));
33 println!(" test(&0): {}", always_false.test(&0));
34 println!(" name: {:?}", always_false.name());
35
36 println!("\n=== RcPredicate always_true/always_false Demo ===\n");
37
38 // RcPredicate::always_true
39 let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
40 println!("RcPredicate::always_true():");
41 println!(" test(&\"hello\"): {}", rc_always_true.test(&"hello".to_string()));
42 println!(" test(&\"world\"): {}", rc_always_true.test(&"world".to_string()));
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!(" test(&\"hello\"): {}", rc_always_false.test(&"hello".to_string()));
49 println!(" test(&\"world\"): {}", rc_always_false.test(&"world".to_string()));
50 println!(" name: {:?}", rc_always_false.name());
51
52 // Can be cloned and reused
53 let rc_clone = rc_always_true.clone();
54 println!("\nAfter cloning, still usable:");
55 println!(
56 " Original: test(&\"test\"): {}",
57 rc_always_true.test(&"test".to_string())
58 );
59 println!(" Clone: test(&\"test\"): {}", rc_clone.test(&"test".to_string()));
60
61 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
62
63 // ArcPredicate::always_true
64 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
65 println!("ArcPredicate::always_true():");
66 println!(" test(&100): {}", arc_always_true.test(&100));
67 println!(" test(&-100): {}", arc_always_true.test(&-100));
68 println!(" name: {:?}", arc_always_true.name());
69
70 // ArcPredicate::always_false
71 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
72 println!("\nArcPredicate::always_false():");
73 println!(" test(&100): {}", arc_always_false.test(&100));
74 println!(" test(&-100): {}", arc_always_false.test(&-100));
75 println!(" name: {:?}", arc_always_false.name());
76
77 println!("\n=== Combining with other predicates ===\n");
78
79 // Combining with always_true (AND)
80 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
81 let combined_and_true = is_positive.and(BoxPredicate::always_true());
82 println!("is_positive AND always_true:");
83 println!(" test(&5): {} (equivalent to is_positive)", combined_and_true.test(&5));
84 println!(
85 " test(&-3): {} (equivalent to is_positive)",
86 combined_and_true.test(&-3)
87 );
88
89 // Combining with always_false (AND)
90 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
91 let combined_and_false = is_positive.and(BoxPredicate::always_false());
92 println!("\nis_positive AND always_false:");
93 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
94 println!(" test(&-3): {} (always false)", combined_and_false.test(&-3));
95
96 // Combining with always_true (OR)
97 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
98 let combined_or_true = is_positive.or(BoxPredicate::always_true());
99 println!("\nis_positive OR always_true:");
100 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
101 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
102
103 // Combining with always_false (OR)
104 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
105 let combined_or_false = is_positive.or(BoxPredicate::always_false());
106 println!("\nis_positive OR always_false:");
107 println!(" test(&5): {} (equivalent to is_positive)", combined_or_false.test(&5));
108 println!(
109 " test(&-3): {} (equivalent to is_positive)",
110 combined_or_false.test(&-3)
111 );
112
113 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
114
115 // Scenario 1: Default pass-all filter
116 let numbers = vec![1, 2, 3, 4, 5];
117 let pass_all = BoxPredicate::<i32>::always_true();
118 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
119 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
120
121 // Scenario 2: Default reject-all filter
122 let numbers = vec![1, 2, 3, 4, 5];
123 let reject_all = BoxPredicate::<i32>::always_false();
124 let filtered: Vec<_> = numbers.iter().copied().filter(reject_all.into_fn()).collect();
125 println!("Default reject all elements: {:?} -> {:?}", numbers, filtered);
126
127 // Scenario 3: Configurable filter
128 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
129 if enable_filter {
130 BoxPredicate::new(|x: &i32| *x > 3)
131 } else {
132 BoxPredicate::always_true()
133 }
134 }
135
136 let numbers = vec![1, 2, 3, 4, 5];
137
138 let filter_enabled = configurable_filter(true);
139 let filtered: Vec<_> = numbers.iter().copied().filter(filter_enabled.into_fn()).collect();
140 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
141
142 let filter_disabled = configurable_filter(false);
143 let filtered: Vec<_> = numbers.iter().copied().filter(filter_disabled.into_fn()).collect();
144 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
145}Sourcepub fn set_name(&mut self, name: &str)
pub fn set_name(&mut self, name: &str)
Examples found in repository?
56fn demo_rc_predicate() {
57 println!("2. RcPredicate Naming Functionality");
58
59 // Using new_with_name
60 let pred1 = RcPredicate::new_with_name("greater_than_10", |x: &i32| *x > 10);
61 println!(" Using new_with_name:");
62 println!(" Name: {:?}", pred1.name());
63 println!(" Test 15: {}", pred1.test(&15));
64
65 // Using set_name
66 let mut pred2 = RcPredicate::new(|x: &i32| *x < 100);
67 println!("\n Using set_name:");
68 println!(" Initial name: {:?}", pred2.name());
69 pred2.set_name("less_than_100");
70 println!(" Name after setting: {:?}", pred2.name());
71 println!(" Test 50: {}", pred2.test(&50));
72
73 // Name is preserved after cloning
74 let pred3 = pred2.clone();
75 println!("\n Name preserved after cloning:");
76 println!(" Cloned name: {:?}", pred3.name());
77 println!(" Test 80: {}\n", pred3.test(&80));
78}Sourcepub fn clear_name(&mut self)
pub fn clear_name(&mut self)
Clears the name of this predicate.
Sourcepub fn always_true() -> Self
pub fn always_true() -> Self
Examples found in repository?
17fn main() {
18 println!("=== BoxPredicate always_true/always_false Demo ===\n");
19
20 // BoxPredicate::always_true
21 let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
22 println!("BoxPredicate::always_true():");
23 println!(" test(&42): {}", always_true.test(&42));
24 println!(" test(&-1): {}", always_true.test(&-1));
25 println!(" test(&0): {}", always_true.test(&0));
26 println!(" name: {:?}", always_true.name());
27
28 // BoxPredicate::always_false
29 let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
30 println!("\nBoxPredicate::always_false():");
31 println!(" test(&42): {}", always_false.test(&42));
32 println!(" test(&-1): {}", always_false.test(&-1));
33 println!(" test(&0): {}", always_false.test(&0));
34 println!(" name: {:?}", always_false.name());
35
36 println!("\n=== RcPredicate always_true/always_false Demo ===\n");
37
38 // RcPredicate::always_true
39 let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
40 println!("RcPredicate::always_true():");
41 println!(" test(&\"hello\"): {}", rc_always_true.test(&"hello".to_string()));
42 println!(" test(&\"world\"): {}", rc_always_true.test(&"world".to_string()));
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!(" test(&\"hello\"): {}", rc_always_false.test(&"hello".to_string()));
49 println!(" test(&\"world\"): {}", rc_always_false.test(&"world".to_string()));
50 println!(" name: {:?}", rc_always_false.name());
51
52 // Can be cloned and reused
53 let rc_clone = rc_always_true.clone();
54 println!("\nAfter cloning, still usable:");
55 println!(
56 " Original: test(&\"test\"): {}",
57 rc_always_true.test(&"test".to_string())
58 );
59 println!(" Clone: test(&\"test\"): {}", rc_clone.test(&"test".to_string()));
60
61 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
62
63 // ArcPredicate::always_true
64 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
65 println!("ArcPredicate::always_true():");
66 println!(" test(&100): {}", arc_always_true.test(&100));
67 println!(" test(&-100): {}", arc_always_true.test(&-100));
68 println!(" name: {:?}", arc_always_true.name());
69
70 // ArcPredicate::always_false
71 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
72 println!("\nArcPredicate::always_false():");
73 println!(" test(&100): {}", arc_always_false.test(&100));
74 println!(" test(&-100): {}", arc_always_false.test(&-100));
75 println!(" name: {:?}", arc_always_false.name());
76
77 println!("\n=== Combining with other predicates ===\n");
78
79 // Combining with always_true (AND)
80 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
81 let combined_and_true = is_positive.and(BoxPredicate::always_true());
82 println!("is_positive AND always_true:");
83 println!(" test(&5): {} (equivalent to is_positive)", combined_and_true.test(&5));
84 println!(
85 " test(&-3): {} (equivalent to is_positive)",
86 combined_and_true.test(&-3)
87 );
88
89 // Combining with always_false (AND)
90 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
91 let combined_and_false = is_positive.and(BoxPredicate::always_false());
92 println!("\nis_positive AND always_false:");
93 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
94 println!(" test(&-3): {} (always false)", combined_and_false.test(&-3));
95
96 // Combining with always_true (OR)
97 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
98 let combined_or_true = is_positive.or(BoxPredicate::always_true());
99 println!("\nis_positive OR always_true:");
100 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
101 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
102
103 // Combining with always_false (OR)
104 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
105 let combined_or_false = is_positive.or(BoxPredicate::always_false());
106 println!("\nis_positive OR always_false:");
107 println!(" test(&5): {} (equivalent to is_positive)", combined_or_false.test(&5));
108 println!(
109 " test(&-3): {} (equivalent to is_positive)",
110 combined_or_false.test(&-3)
111 );
112
113 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
114
115 // Scenario 1: Default pass-all filter
116 let numbers = vec![1, 2, 3, 4, 5];
117 let pass_all = BoxPredicate::<i32>::always_true();
118 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
119 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
120
121 // Scenario 2: Default reject-all filter
122 let numbers = vec![1, 2, 3, 4, 5];
123 let reject_all = BoxPredicate::<i32>::always_false();
124 let filtered: Vec<_> = numbers.iter().copied().filter(reject_all.into_fn()).collect();
125 println!("Default reject all elements: {:?} -> {:?}", numbers, filtered);
126
127 // Scenario 3: Configurable filter
128 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
129 if enable_filter {
130 BoxPredicate::new(|x: &i32| *x > 3)
131 } else {
132 BoxPredicate::always_true()
133 }
134 }
135
136 let numbers = vec![1, 2, 3, 4, 5];
137
138 let filter_enabled = configurable_filter(true);
139 let filtered: Vec<_> = numbers.iter().copied().filter(filter_enabled.into_fn()).collect();
140 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
141
142 let filter_disabled = configurable_filter(false);
143 let filtered: Vec<_> = numbers.iter().copied().filter(filter_disabled.into_fn()).collect();
144 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
145}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 found in repository?
17fn main() {
18 println!("=== BoxPredicate always_true/always_false Demo ===\n");
19
20 // BoxPredicate::always_true
21 let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
22 println!("BoxPredicate::always_true():");
23 println!(" test(&42): {}", always_true.test(&42));
24 println!(" test(&-1): {}", always_true.test(&-1));
25 println!(" test(&0): {}", always_true.test(&0));
26 println!(" name: {:?}", always_true.name());
27
28 // BoxPredicate::always_false
29 let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
30 println!("\nBoxPredicate::always_false():");
31 println!(" test(&42): {}", always_false.test(&42));
32 println!(" test(&-1): {}", always_false.test(&-1));
33 println!(" test(&0): {}", always_false.test(&0));
34 println!(" name: {:?}", always_false.name());
35
36 println!("\n=== RcPredicate always_true/always_false Demo ===\n");
37
38 // RcPredicate::always_true
39 let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
40 println!("RcPredicate::always_true():");
41 println!(" test(&\"hello\"): {}", rc_always_true.test(&"hello".to_string()));
42 println!(" test(&\"world\"): {}", rc_always_true.test(&"world".to_string()));
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!(" test(&\"hello\"): {}", rc_always_false.test(&"hello".to_string()));
49 println!(" test(&\"world\"): {}", rc_always_false.test(&"world".to_string()));
50 println!(" name: {:?}", rc_always_false.name());
51
52 // Can be cloned and reused
53 let rc_clone = rc_always_true.clone();
54 println!("\nAfter cloning, still usable:");
55 println!(
56 " Original: test(&\"test\"): {}",
57 rc_always_true.test(&"test".to_string())
58 );
59 println!(" Clone: test(&\"test\"): {}", rc_clone.test(&"test".to_string()));
60
61 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
62
63 // ArcPredicate::always_true
64 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
65 println!("ArcPredicate::always_true():");
66 println!(" test(&100): {}", arc_always_true.test(&100));
67 println!(" test(&-100): {}", arc_always_true.test(&-100));
68 println!(" name: {:?}", arc_always_true.name());
69
70 // ArcPredicate::always_false
71 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
72 println!("\nArcPredicate::always_false():");
73 println!(" test(&100): {}", arc_always_false.test(&100));
74 println!(" test(&-100): {}", arc_always_false.test(&-100));
75 println!(" name: {:?}", arc_always_false.name());
76
77 println!("\n=== Combining with other predicates ===\n");
78
79 // Combining with always_true (AND)
80 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
81 let combined_and_true = is_positive.and(BoxPredicate::always_true());
82 println!("is_positive AND always_true:");
83 println!(" test(&5): {} (equivalent to is_positive)", combined_and_true.test(&5));
84 println!(
85 " test(&-3): {} (equivalent to is_positive)",
86 combined_and_true.test(&-3)
87 );
88
89 // Combining with always_false (AND)
90 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
91 let combined_and_false = is_positive.and(BoxPredicate::always_false());
92 println!("\nis_positive AND always_false:");
93 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
94 println!(" test(&-3): {} (always false)", combined_and_false.test(&-3));
95
96 // Combining with always_true (OR)
97 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
98 let combined_or_true = is_positive.or(BoxPredicate::always_true());
99 println!("\nis_positive OR always_true:");
100 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
101 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
102
103 // Combining with always_false (OR)
104 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
105 let combined_or_false = is_positive.or(BoxPredicate::always_false());
106 println!("\nis_positive OR always_false:");
107 println!(" test(&5): {} (equivalent to is_positive)", combined_or_false.test(&5));
108 println!(
109 " test(&-3): {} (equivalent to is_positive)",
110 combined_or_false.test(&-3)
111 );
112
113 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
114
115 // Scenario 1: Default pass-all filter
116 let numbers = vec![1, 2, 3, 4, 5];
117 let pass_all = BoxPredicate::<i32>::always_true();
118 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
119 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
120
121 // Scenario 2: Default reject-all filter
122 let numbers = vec![1, 2, 3, 4, 5];
123 let reject_all = BoxPredicate::<i32>::always_false();
124 let filtered: Vec<_> = numbers.iter().copied().filter(reject_all.into_fn()).collect();
125 println!("Default reject all elements: {:?} -> {:?}", numbers, filtered);
126
127 // Scenario 3: Configurable filter
128 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
129 if enable_filter {
130 BoxPredicate::new(|x: &i32| *x > 3)
131 } else {
132 BoxPredicate::always_true()
133 }
134 }
135
136 let numbers = vec![1, 2, 3, 4, 5];
137
138 let filter_enabled = configurable_filter(true);
139 let filtered: Vec<_> = numbers.iter().copied().filter(filter_enabled.into_fn()).collect();
140 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
141
142 let filter_disabled = configurable_filter(false);
143 let filtered: Vec<_> = numbers.iter().copied().filter(filter_disabled.into_fn()).collect();
144 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
145}Sourcepub fn and<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
P: Predicate<T> + 'static,
pub fn and<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
P: Predicate<T> + 'static,
Returns a predicate that represents the logical AND of this predicate and another.
This method borrows self; the original shared predicate remains
usable.
§Parameters
other- The other predicate to combine with.
§Returns
A new predicate representing the logical AND.
Examples found in repository?
103fn rc_predicate_examples() {
104 println!("--- 3. RcPredicate Examples (Single-threaded Reuse) ---");
105
106 let is_positive = RcPredicate::new(|x: &i32| *x > 0);
107 let is_even = RcPredicate::new(|x: &i32| x % 2 == 0);
108
109 // Multiple compositions without consuming the original
110 let positive_and_even = is_positive.and(is_even.clone());
111 let positive_or_even = is_positive.or(is_even.clone());
112
113 println!("Original predicates still available:");
114 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
115 println!(" is_even.test(&4) = {}", is_even.test(&4));
116
117 println!("Combined predicates:");
118 println!(" positive_and_even.test(&4) = {}", positive_and_even.test(&4));
119 println!(" positive_or_even.test(&5) = {}", positive_or_even.test(&5));
120
121 // Cloning
122 let cloned = is_positive.clone();
123 println!("Cloned predicate: {}", cloned.test(&10));
124}
125
126/// ArcPredicate examples - multi-threaded scenarios
127fn arc_predicate_examples() {
128 println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
129
130 let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
131 let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
132
133 // Create combined predicate
134 let combined = is_positive.and(is_even);
135
136 // Use in multiple threads
137 let handles: Vec<_> = (0..3)
138 .map(|i| {
139 let pred = combined.clone();
140 std::thread::spawn(move || {
141 let value = i * 2;
142 println!(" Thread {} testing {}: {}", i, value, pred.test(&value));
143 })
144 })
145 .collect();
146
147 for handle in handles {
148 handle.join().expect("thread should not panic");
149 }
150
151 // Original predicates still usable
152 println!("Original predicates still available in main thread:");
153 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
154}
155
156/// Logical composition examples
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}
209
210/// Interior mutability examples
211fn interior_mutability_examples() {
212 println!("--- 6. Interior Mutability Examples ---");
213
214 // BoxPredicate with counter (RefCell)
215 println!("BoxPredicate with counter:");
216 let count = RefCell::new(0);
217 let pred = BoxPredicate::new(move |x: &i32| {
218 *count.borrow_mut() += 1;
219 *x > 0
220 });
221 println!(" Test 5: {}", pred.test(&5));
222 println!(" Test -3: {}", pred.test(&-3));
223 println!(" Test 10: {}", pred.test(&10));
224 // Note: count is moved into the closure, so we can't access it here
225
226 // RcPredicate with cache (RefCell + HashMap)
227 println!("\nRcPredicate with cache:");
228 let cache: RefCell<HashMap<i32, bool>> = RefCell::new(HashMap::new());
229 let expensive_pred = RcPredicate::new(move |x: &i32| {
230 let mut c = cache.borrow_mut();
231 *c.entry(*x).or_insert_with(|| {
232 println!(" Computing result for {} (expensive operation)", x);
233 *x > 0 && x % 2 == 0
234 })
235 });
236
237 println!(" First test 4:");
238 println!(" Result: {}", expensive_pred.test(&4));
239 println!(" Test 4 again (using cache):");
240 println!(" Result: {}", expensive_pred.test(&4));
241 println!(" Test 3:");
242 println!(" Result: {}", expensive_pred.test(&3));
243
244 // ArcPredicate with thread-safe counter (Mutex)
245 println!("\nArcPredicate with thread-safe counter:");
246 let counter = Arc::new(Mutex::new(0));
247 let pred = ArcPredicate::new({
248 let counter = Arc::clone(&counter);
249 move |x: &i32| {
250 let mut c = counter.lock().expect("mutex should not be poisoned");
251 *c += 1;
252 *x > 0
253 }
254 });
255
256 let pred_clone = pred.clone();
257 let counter_clone = Arc::clone(&counter);
258
259 let handle = std::thread::spawn(move || {
260 pred_clone.test(&5);
261 pred_clone.test(&10);
262 });
263
264 pred.test(&3);
265 handle.join().expect("thread should not panic");
266
267 println!(
268 " Total call count: {}",
269 counter_clone.lock().expect("mutex should not be poisoned")
270 );
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 = RcPredicate::new_with_name("name_not_empty", |user: &User| !user.name.is_empty());
286
287 let age_valid = RcPredicate::new_with_name("age_between_18_120", |user: &User| user.age >= 18 && user.age <= 120);
288
289 let email_valid = RcPredicate::new_with_name("email_contains_at", |user: &User| user.email.contains('@'));
290
291 let all_valid = name_valid.and(age_valid.clone()).and(email_valid.clone());
292
293 let user1 = User {
294 name: "Alice".to_string(),
295 age: 25,
296 email: "alice@example.com".to_string(),
297 };
298
299 let user2 = User {
300 name: "".to_string(),
301 age: 25,
302 email: "bob@example.com".to_string(),
303 };
304
305 println!(" user1 validation: {}", all_valid.test(&user1));
306 println!(" user2 validation: {}", all_valid.test(&user2));
307
308 // Filter pipeline
309 println!("\nScenario 2: Data Filtering Pipeline");
310 let numbers: Vec<i32> = (-10..=10).collect();
311
312 let positive = |x: &i32| *x > 0;
313 let even = |x: &i32| x % 2 == 0;
314 let less_than_eight = |x: &i32| *x < 8;
315
316 let filtered: Vec<i32> = numbers
317 .iter()
318 .filter(|x| positive.test(x))
319 .filter(|x| even.test(x))
320 .filter(|x| less_than_eight.test(x))
321 .copied()
322 .collect();
323
324 println!(" Filtered numbers: {:?}", filtered);
325
326 // Strategy pattern
327 println!("\nScenario 3: Strategy Pattern");
328 let mut strategies: HashMap<&str, RcPredicate<i32>> = HashMap::new();
329 strategies.insert("positive", RcPredicate::new(|x: &i32| *x > 0));
330 strategies.insert("negative", RcPredicate::new(|x: &i32| *x < 0));
331 strategies.insert("even", RcPredicate::new(|x: &i32| x % 2 == 0));
332
333 let test_value = 4;
334 for (name, pred) in strategies.iter() {
335 println!(" {} strategy test {}: {}", name, test_value, pred.test(&test_value));
336 }
337}Sourcepub fn or<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
P: Predicate<T> + 'static,
pub fn or<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
P: Predicate<T> + 'static,
Returns a predicate that represents the logical OR of this predicate and another.
This method borrows self; the original shared predicate remains
usable.
§Parameters
other- The other predicate to combine with.
§Returns
A new predicate representing the logical OR.
Examples found in repository?
103fn rc_predicate_examples() {
104 println!("--- 3. RcPredicate Examples (Single-threaded Reuse) ---");
105
106 let is_positive = RcPredicate::new(|x: &i32| *x > 0);
107 let is_even = RcPredicate::new(|x: &i32| x % 2 == 0);
108
109 // Multiple compositions without consuming the original
110 let positive_and_even = is_positive.and(is_even.clone());
111 let positive_or_even = is_positive.or(is_even.clone());
112
113 println!("Original predicates still available:");
114 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
115 println!(" is_even.test(&4) = {}", is_even.test(&4));
116
117 println!("Combined predicates:");
118 println!(" positive_and_even.test(&4) = {}", positive_and_even.test(&4));
119 println!(" positive_or_even.test(&5) = {}", positive_or_even.test(&5));
120
121 // Cloning
122 let cloned = is_positive.clone();
123 println!("Cloned predicate: {}", cloned.test(&10));
124}
125
126/// ArcPredicate examples - multi-threaded scenarios
127fn arc_predicate_examples() {
128 println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
129
130 let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
131 let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
132
133 // Create combined predicate
134 let combined = is_positive.and(is_even);
135
136 // Use in multiple threads
137 let handles: Vec<_> = (0..3)
138 .map(|i| {
139 let pred = combined.clone();
140 std::thread::spawn(move || {
141 let value = i * 2;
142 println!(" Thread {} testing {}: {}", i, value, pred.test(&value));
143 })
144 })
145 .collect();
146
147 for handle in handles {
148 handle.join().expect("thread should not panic");
149 }
150
151 // Original predicates still usable
152 println!("Original predicates still available in main thread:");
153 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
154}
155
156/// Logical composition examples
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}Sourcepub fn nand<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
P: Predicate<T> + 'static,
pub fn nand<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
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).
This method borrows self; the original shared predicate remains
usable.
§Parameters
other- The other predicate to combine with.
§Returns
A new predicate representing the logical NAND.
Examples found in repository?
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}Sourcepub fn xor<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
P: Predicate<T> + 'static,
pub fn xor<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
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.
This method borrows self; the original shared predicate remains
usable.
§Parameters
other- The other predicate to combine with.
§Returns
A new predicate representing the logical XOR.
Examples found in repository?
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}Sourcepub fn nor<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
P: Predicate<T> + 'static,
pub fn nor<P>(&self, other: P) -> RcPredicate<T>where
T: 'static,
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).
This method borrows self; the original shared predicate remains
usable.
§Parameters
other- The other predicate to combine with.
§Returns
A new predicate representing the logical NOR.
Examples found in repository?
157fn logical_composition_examples() {
158 println!("--- 5. Logical Composition Examples ---");
159
160 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
161 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
162 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
163
164 // AND composition
165 let positive_and_even = positive.and(even.clone());
166 println!("positive AND even: name={:?}", positive_and_even.name());
167 println!(" Test 4: {}", positive_and_even.test(&4));
168 println!(" Test 5: {}", positive_and_even.test(&5));
169
170 // OR composition
171 let positive_or_even = positive.or(even.clone());
172 println!("positive OR even: name={:?}", positive_or_even.name());
173 println!(" Test -2: {}", positive_or_even.test(&-2));
174 println!(" Test 5: {}", positive_or_even.test(&5));
175
176 // NOT composition
177 let not_positive = !&positive;
178 println!("NOT positive: name={:?}", not_positive.name());
179 println!(" Test 5: {}", not_positive.test(&5));
180 println!(" Test -3: {}", not_positive.test(&-3));
181
182 // NAND composition
183 let nand = positive.nand(even.clone());
184 println!("positive NAND even: name={:?}", nand.name());
185 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
186 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
187
188 // XOR composition
189 let xor = positive.xor(even.clone());
190 println!("positive XOR even: name={:?}", xor.name());
191 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
192 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
193 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
194
195 // NOR composition
196 let nor = positive.nor(even.clone());
197 println!("positive NOR even: name={:?}", nor.name());
198 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
199 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
200 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
201 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
202
203 // Complex composition
204 let complex = positive.and(even.clone()).and(less_than_ten.clone());
205 println!("Complex composition: name={:?}", complex.name());
206 println!(" Test 4: {}", complex.test(&4));
207 println!(" Test 12: {}", complex.test(&12));
208}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> Not for &RcPredicate<T>where
T: 'static,
impl<T> Not for &RcPredicate<T>where
T: 'static,
Source§impl<T> Not for RcPredicate<T>where
T: 'static,
impl<T> Not for RcPredicate<T>where
T: 'static,
Source§impl<T> Predicate<T> for RcPredicate<T>
impl<T> 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>where
Self: 'static,
fn into_box(self) -> BoxPredicate<T>where
Self: 'static,
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>where
Self: 'static,
fn to_box(&self) -> BoxPredicate<T>where
Self: 'static,
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