pub struct BoxPredicate<T> { /* private fields */ }Expand description
A Box-based predicate with single ownership.
This type is suitable for one-time use scenarios where the predicate does
not need to be cloned or shared. Composition methods consume self,
reflecting the single-ownership model.
§Examples
use prism3_function::predicate::{Predicate, BoxPredicate};
let pred = BoxPredicate::new(|x: &i32| *x > 0);
assert!(pred.test(&5));
// Chaining consumes the predicate
let combined = pred.and(BoxPredicate::new(|x| x % 2 == 0));
assert!(combined.test(&4));§Author
Haixing Hu
Implementations§
Source§impl<T: 'static> BoxPredicate<T>
impl<T: 'static> BoxPredicate<T>
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new BoxPredicate from a closure.
§Parameters
f- The closure to wrap.
§Returns
A new BoxPredicate instance.
Examples found in repository?
More examples
78fn box_predicate_examples() {
79 println!("--- 2. BoxPredicate Examples (Single Ownership) ---");
80
81 // Basic BoxPredicate
82 let pred = BoxPredicate::new(|x: &i32| *x > 0);
83 println!("BoxPredicate test 5: {}", pred.test(&5));
84
85 // Named predicate for better debugging
86 let named_pred =
87 BoxPredicate::new_with_name("is_positive_even", |x: &i32| *x > 0 && x % 2 == 0);
88 println!("Predicate name: {:?}", named_pred.name());
89 println!("Test 4: {}", named_pred.test(&4));
90
91 // Method chaining - consumes self
92 let positive = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
93 let even = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
94 let combined = positive.and(even);
95 println!("Combined predicate name: {:?}", combined.name());
96 println!("Test 4: {}", combined.test(&4));
97}
98
99/// RcPredicate examples - single-threaded reuse
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}23fn demo_box_predicate() {
24 println!("1. BoxPredicate Naming Functionality");
25
26 // Create a predicate with name using new_with_name
27 let pred1 = BoxPredicate::new_with_name("is_positive", |x: &i32| *x > 0);
28 println!(" Created with new_with_name:");
29 println!(" Name: {:?}", pred1.name());
30 println!(" Test 5: {}", pred1.test(&5));
31
32 // Set name for an existing predicate using set_name
33 let mut pred2 = BoxPredicate::new(|x: &i32| x % 2 == 0);
34 println!("\n Created with new then set_name:");
35 println!(" Initial name: {:?}", pred2.name());
36 pred2.set_name("is_even");
37 println!(" Name after setting: {:?}", pred2.name());
38 println!(" Test 4: {}", pred2.test(&4));
39
40 // Combined predicates automatically generate new names
41 let pred3 = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
42 let pred4 = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
43 let combined = pred3.and(pred4);
44 println!("\n Combined predicate name:");
45 println!(" Auto-generated name: {:?}", combined.name());
46 println!(" Test 4: {}\n", combined.test(&4));
47}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}16fn main() {
17 println!("=== MutatorOnce Conditional Execution Examples ===\n");
18
19 // 1. Basic conditional execution - when condition is satisfied
20 println!("1. Basic conditional execution - when condition is satisfied");
21 let data = vec![1, 2, 3];
22 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
23 println!(" Extending vector with data: {:?}", data);
24 x.extend(data);
25 });
26 let conditional = mutator.when(|x: &Vec<i32>| {
27 println!(" Checking condition: !x.is_empty()");
28 !x.is_empty()
29 });
30
31 let mut target = vec![0];
32 println!(" Initial: {:?}", target);
33 conditional.mutate_once(&mut target);
34 println!(" Result: {:?}\n", target);
35
36 // 2. Conditional execution - when condition is not satisfied
37 println!("2. Conditional execution - when condition is not satisfied");
38 let data = vec![4, 5, 6];
39 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
40 println!(" This should not be executed");
41 x.extend(data);
42 });
43 let conditional = mutator.when(|x: &Vec<i32>| {
44 println!(" Checking condition: x.len() > 10");
45 x.len() > 10
46 });
47
48 let mut target = vec![0];
49 println!(" Initial: {:?}", target);
50 conditional.mutate_once(&mut target);
51 println!(" Result: {:?} (unchanged)\n", target);
52
53 // 3. Using BoxPredicate
54 println!("3. Using BoxPredicate");
55 let pred = BoxPredicate::new(|x: &Vec<i32>| {
56 println!(" Predicate: checking if vector is not empty");
57 !x.is_empty()
58 });
59 let data = vec![7, 8, 9];
60 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
61 println!(" Adding data: {:?}", data);
62 x.extend(data);
63 });
64 let conditional = mutator.when(pred);
65
66 let mut target = vec![0];
67 println!(" Initial: {:?}", target);
68 conditional.mutate_once(&mut target);
69 println!(" Result: {:?}\n", target);
70
71 // 4. Using composed predicate
72 println!("4. Using composed predicate");
73 let pred = (|x: &Vec<i32>| {
74 println!(" Condition 1: !x.is_empty()");
75 !x.is_empty()
76 })
77 .and(|x: &Vec<i32>| {
78 println!(" Condition 2: x.len() < 10");
79 x.len() < 10
80 });
81 let data = vec![10, 11, 12];
82 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
83 println!(" Adding data: {:?}", data);
84 x.extend(data);
85 });
86 let conditional = mutator.when(pred);
87
88 let mut target = vec![0];
89 println!(" Initial: {:?}", target);
90 conditional.mutate_once(&mut target);
91 println!(" Result: {:?}\n", target);
92
93 // 5. If-then-else with or_else - when branch
94 println!("5. If-then-else with or_else - when branch");
95 let data1 = vec![1, 2, 3];
96 let data2 = vec![99];
97 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
98 println!(" When branch: adding {:?}", data1);
99 x.extend(data1);
100 })
101 .when(|x: &Vec<i32>| {
102 println!(" Checking: !x.is_empty()");
103 !x.is_empty()
104 })
105 .or_else(move |x: &mut Vec<i32>| {
106 println!(" Else branch: adding {:?}", data2);
107 x.extend(data2);
108 });
109
110 let mut target = vec![0];
111 println!(" Initial: {:?}", target);
112 mutator.mutate_once(&mut target);
113 println!(" Result: {:?}\n", target);
114
115 // 6. If-then-else with or_else - else branch
116 println!("6. If-then-else with or_else - else branch");
117 let data1 = vec![4, 5, 6];
118 let data2 = vec![99];
119 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
120 println!(" When branch: adding {:?}", data1);
121 x.extend(data1);
122 })
123 .when(|x: &Vec<i32>| {
124 println!(" Checking: x.is_empty()");
125 x.is_empty()
126 })
127 .or_else(move |x: &mut Vec<i32>| {
128 println!(" Else branch: adding {:?}", data2);
129 x.extend(data2);
130 });
131
132 let mut target = vec![0];
133 println!(" Initial: {:?}", target);
134 mutator.mutate_once(&mut target);
135 println!(" Result: {:?}\n", target);
136
137 // 7. Conditional with integers
138 println!("7. Conditional with integers");
139 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
140 println!(" Multiplying by 2");
141 *x *= 2;
142 })
143 .when(|x: &i32| {
144 println!(" Checking: *x > 0");
145 *x > 0
146 });
147
148 let mut positive = 5;
149 println!(" Initial (positive): {}", positive);
150 mutator.mutate_once(&mut positive);
151 println!(" Result: {}\n", positive);
152
153 // 8. Conditional with integers - not executed
154 println!("8. Conditional with integers - not executed");
155 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
156 println!(" This should not be executed");
157 *x *= 2;
158 })
159 .when(|x: &i32| {
160 println!(" Checking: *x > 0");
161 *x > 0
162 });
163
164 let mut negative = -5;
165 println!(" Initial (negative): {}", negative);
166 mutator.mutate_once(&mut negative);
167 println!(" Result: {} (unchanged)\n", negative);
168
169 // 9. Chaining conditional mutators
170 println!("9. Chaining conditional mutators");
171 let data1 = vec![1, 2];
172 let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
173 println!(" First mutator: adding {:?}", data1);
174 x.extend(data1);
175 })
176 .when(|x: &Vec<i32>| {
177 println!(" First condition: !x.is_empty()");
178 !x.is_empty()
179 });
180
181 let data2 = vec![3, 4];
182 let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
183 println!(" Second mutator: adding {:?}", data2);
184 x.extend(data2);
185 })
186 .when(|x: &Vec<i32>| {
187 println!(" Second condition: x.len() < 10");
188 x.len() < 10
189 });
190
191 let chained = cond1.and_then(cond2);
192
193 let mut target = vec![0];
194 println!(" Initial: {:?}", target);
195 chained.mutate_once(&mut target);
196 println!(" Result: {:?}\n", target);
197
198 // 10. Complex conditional chain
199 println!("10. Complex conditional chain");
200 let data1 = vec![1, 2];
201 let data2 = vec![99];
202 let data3 = vec![5, 6];
203
204 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
205 println!(" When branch: adding {:?}", data1);
206 x.extend(data1);
207 })
208 .when(|x: &Vec<i32>| {
209 println!(" Checking: !x.is_empty()");
210 !x.is_empty()
211 })
212 .or_else(move |x: &mut Vec<i32>| {
213 println!(" Else branch: adding {:?}", data2);
214 x.extend(data2);
215 })
216 .and_then(move |x: &mut Vec<i32>| {
217 println!(" Final step: adding {:?}", data3);
218 x.extend(data3);
219 });
220
221 let mut target = vec![0];
222 println!(" Initial: {:?}", target);
223 mutator.mutate_once(&mut target);
224 println!(" Result: {:?}\n", target);
225
226 // 11. Real-world scenario: data validation and processing
227 println!("11. Real-world scenario: data validation and processing");
228
229 struct DataProcessor {
230 on_valid: Option<BoxMutatorOnce<Vec<String>>>,
231 on_invalid: Option<BoxMutatorOnce<Vec<String>>>,
232 }
233
234 impl DataProcessor {
235 fn new<V, I>(on_valid: V, on_invalid: I) -> Self
236 where
237 V: FnOnce(&mut Vec<String>) + 'static,
238 I: FnOnce(&mut Vec<String>) + 'static,
239 {
240 Self {
241 on_valid: Some(BoxMutatorOnce::new(on_valid)),
242 on_invalid: Some(BoxMutatorOnce::new(on_invalid)),
243 }
244 }
245
246 fn process(mut self, data: &mut Vec<String>) {
247 let is_valid = !data.is_empty() && data.iter().all(|s| !s.is_empty());
248 println!(
249 " Data validation: {}",
250 if is_valid { "VALID" } else { "INVALID" }
251 );
252
253 if is_valid {
254 if let Some(callback) = self.on_valid.take() {
255 callback.mutate_once(data);
256 }
257 } else if let Some(callback) = self.on_invalid.take() {
258 callback.mutate_once(data);
259 }
260 }
261 }
262
263 let valid_suffix = vec!["processed".to_string()];
264 let invalid_marker = vec!["[INVALID]".to_string()];
265
266 let processor = DataProcessor::new(
267 move |data| {
268 println!(" Valid data callback: adding suffix");
269 data.extend(valid_suffix);
270 },
271 move |data| {
272 println!(" Invalid data callback: adding error marker");
273 data.clear();
274 data.extend(invalid_marker);
275 },
276 );
277
278 let mut valid_data = vec!["item1".to_string(), "item2".to_string()];
279 println!(" Processing valid data: {:?}", valid_data);
280 processor.process(&mut valid_data);
281 println!(" Result: {:?}\n", valid_data);
282
283 println!("=== Examples completed ===");
284}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 BoxPredicate from a closure.
§Parameters
name- The name for this predicate.f- The closure to wrap.
§Returns
A new named BoxPredicate instance.
Examples found in repository?
78fn box_predicate_examples() {
79 println!("--- 2. BoxPredicate Examples (Single Ownership) ---");
80
81 // Basic BoxPredicate
82 let pred = BoxPredicate::new(|x: &i32| *x > 0);
83 println!("BoxPredicate test 5: {}", pred.test(&5));
84
85 // Named predicate for better debugging
86 let named_pred =
87 BoxPredicate::new_with_name("is_positive_even", |x: &i32| *x > 0 && x % 2 == 0);
88 println!("Predicate name: {:?}", named_pred.name());
89 println!("Test 4: {}", named_pred.test(&4));
90
91 // Method chaining - consumes self
92 let positive = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
93 let even = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
94 let combined = positive.and(even);
95 println!("Combined predicate name: {:?}", combined.name());
96 println!("Test 4: {}", combined.test(&4));
97}More examples
23fn demo_box_predicate() {
24 println!("1. BoxPredicate Naming Functionality");
25
26 // Create a predicate with name using new_with_name
27 let pred1 = BoxPredicate::new_with_name("is_positive", |x: &i32| *x > 0);
28 println!(" Created with new_with_name:");
29 println!(" Name: {:?}", pred1.name());
30 println!(" Test 5: {}", pred1.test(&5));
31
32 // Set name for an existing predicate using set_name
33 let mut pred2 = BoxPredicate::new(|x: &i32| x % 2 == 0);
34 println!("\n Created with new then set_name:");
35 println!(" Initial name: {:?}", pred2.name());
36 pred2.set_name("is_even");
37 println!(" Name after setting: {:?}", pred2.name());
38 println!(" Test 4: {}", pred2.test(&4));
39
40 // Combined predicates automatically generate new names
41 let pred3 = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
42 let pred4 = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
43 let combined = pred3.and(pred4);
44 println!("\n Combined predicate name:");
45 println!(" Auto-generated name: {:?}", combined.name());
46 println!(" Test 4: {}\n", combined.test(&4));
47}Sourcepub fn always_true() -> Self
pub fn always_true() -> Self
Creates a predicate that always returns true.
§Returns
A new BoxPredicate that always returns true.
§Examples
use prism3_function::predicate::{Predicate, BoxPredicate};
let pred: BoxPredicate<i32> = BoxPredicate::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 BoxPredicate that always returns false.
§Examples
use prism3_function::predicate::{Predicate, BoxPredicate};
let pred: BoxPredicate<i32> = BoxPredicate::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?
78fn box_predicate_examples() {
79 println!("--- 2. BoxPredicate Examples (Single Ownership) ---");
80
81 // Basic BoxPredicate
82 let pred = BoxPredicate::new(|x: &i32| *x > 0);
83 println!("BoxPredicate test 5: {}", pred.test(&5));
84
85 // Named predicate for better debugging
86 let named_pred =
87 BoxPredicate::new_with_name("is_positive_even", |x: &i32| *x > 0 && x % 2 == 0);
88 println!("Predicate name: {:?}", named_pred.name());
89 println!("Test 4: {}", named_pred.test(&4));
90
91 // Method chaining - consumes self
92 let positive = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
93 let even = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
94 let combined = positive.and(even);
95 println!("Combined predicate name: {:?}", combined.name());
96 println!("Test 4: {}", combined.test(&4));
97}More examples
23fn demo_box_predicate() {
24 println!("1. BoxPredicate Naming Functionality");
25
26 // Create a predicate with name using new_with_name
27 let pred1 = BoxPredicate::new_with_name("is_positive", |x: &i32| *x > 0);
28 println!(" Created with new_with_name:");
29 println!(" Name: {:?}", pred1.name());
30 println!(" Test 5: {}", pred1.test(&5));
31
32 // Set name for an existing predicate using set_name
33 let mut pred2 = BoxPredicate::new(|x: &i32| x % 2 == 0);
34 println!("\n Created with new then set_name:");
35 println!(" Initial name: {:?}", pred2.name());
36 pred2.set_name("is_even");
37 println!(" Name after setting: {:?}", pred2.name());
38 println!(" Test 4: {}", pred2.test(&4));
39
40 // Combined predicates automatically generate new names
41 let pred3 = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
42 let pred4 = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
43 let combined = pred3.and(pred4);
44 println!("\n Combined predicate name:");
45 println!(" Auto-generated name: {:?}", combined.name());
46 println!(" Test 4: {}\n", combined.test(&4));
47}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?
23fn demo_box_predicate() {
24 println!("1. BoxPredicate Naming Functionality");
25
26 // Create a predicate with name using new_with_name
27 let pred1 = BoxPredicate::new_with_name("is_positive", |x: &i32| *x > 0);
28 println!(" Created with new_with_name:");
29 println!(" Name: {:?}", pred1.name());
30 println!(" Test 5: {}", pred1.test(&5));
31
32 // Set name for an existing predicate using set_name
33 let mut pred2 = BoxPredicate::new(|x: &i32| x % 2 == 0);
34 println!("\n Created with new then set_name:");
35 println!(" Initial name: {:?}", pred2.name());
36 pred2.set_name("is_even");
37 println!(" Name after setting: {:?}", pred2.name());
38 println!(" Test 4: {}", pred2.test(&4));
39
40 // Combined predicates automatically generate new names
41 let pred3 = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
42 let pred4 = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
43 let combined = pred3.and(pred4);
44 println!("\n Combined predicate name:");
45 println!(" Auto-generated name: {:?}", combined.name());
46 println!(" Test 4: {}\n", combined.test(&4));
47}Sourcepub fn and<P>(self, other: P) -> BoxPredicate<T>where
P: Predicate<T> + 'static,
pub fn and<P>(self, other: P) -> BoxPredicate<T>where
P: Predicate<T> + 'static,
Returns a predicate that represents the logical AND of this predicate and another.
This method consumes self due to single-ownership semantics.
§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 - Another
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new BoxPredicate representing the logical AND.
§Examples
§Combining with closures
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
// Note: is_positive is moved here, so it's no longer usable
let combined = is_positive.and(is_even);
assert!(combined.test(&4)); // positive and even
assert!(!combined.test(&3)); // positive but odd
assert!(!combined.test(&-2)); // even but negative
// is_positive.test(&5); // This would not compile - is_positive was moved§Combining with function pointers
use prism3_function::predicate::{Predicate, BoxPredicate};
fn is_even(x: &i32) -> bool { x % 2 == 0 }
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let combined = is_positive.and(is_even);
assert!(combined.test(&4));
assert!(!combined.test(&3));§Combining with other BoxPredicate
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
let combined = is_positive.and(is_even);
assert!(combined.test(&4));
assert!(!combined.test(&3));§Chained composition
use prism3_function::predicate::{Predicate, BoxPredicate};
let pred = BoxPredicate::new(|x: &i32| *x > 0)
.and(|x: &i32| x % 2 == 0)
.and(|x: &i32| *x < 100);
assert!(pred.test(&42)); // positive, even, less than 100
assert!(!pred.test(&101)); // does not satisfy less than 100§Preserving original predicates with clone
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
// Clone the predicates to preserve them for later use
let combined = is_positive.clone().and(is_even.clone());
assert!(combined.test(&4));
// Original predicates are still usable
assert!(is_positive.test(&5));
assert!(is_even.test(&6));Examples found in repository?
78fn box_predicate_examples() {
79 println!("--- 2. BoxPredicate Examples (Single Ownership) ---");
80
81 // Basic BoxPredicate
82 let pred = BoxPredicate::new(|x: &i32| *x > 0);
83 println!("BoxPredicate test 5: {}", pred.test(&5));
84
85 // Named predicate for better debugging
86 let named_pred =
87 BoxPredicate::new_with_name("is_positive_even", |x: &i32| *x > 0 && x % 2 == 0);
88 println!("Predicate name: {:?}", named_pred.name());
89 println!("Test 4: {}", named_pred.test(&4));
90
91 // Method chaining - consumes self
92 let positive = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
93 let even = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
94 let combined = positive.and(even);
95 println!("Combined predicate name: {:?}", combined.name());
96 println!("Test 4: {}", combined.test(&4));
97}More examples
23fn demo_box_predicate() {
24 println!("1. BoxPredicate Naming Functionality");
25
26 // Create a predicate with name using new_with_name
27 let pred1 = BoxPredicate::new_with_name("is_positive", |x: &i32| *x > 0);
28 println!(" Created with new_with_name:");
29 println!(" Name: {:?}", pred1.name());
30 println!(" Test 5: {}", pred1.test(&5));
31
32 // Set name for an existing predicate using set_name
33 let mut pred2 = BoxPredicate::new(|x: &i32| x % 2 == 0);
34 println!("\n Created with new then set_name:");
35 println!(" Initial name: {:?}", pred2.name());
36 pred2.set_name("is_even");
37 println!(" Name after setting: {:?}", pred2.name());
38 println!(" Test 4: {}", pred2.test(&4));
39
40 // Combined predicates automatically generate new names
41 let pred3 = BoxPredicate::new_with_name("positive", |x: &i32| *x > 0);
42 let pred4 = BoxPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
43 let combined = pred3.and(pred4);
44 println!("\n Combined predicate name:");
45 println!(" Auto-generated name: {:?}", combined.name());
46 println!(" Test 4: {}\n", combined.test(&4));
47}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 or<P>(self, other: P) -> BoxPredicate<T>where
P: Predicate<T> + 'static,
pub fn or<P>(self, other: P) -> BoxPredicate<T>where
P: Predicate<T> + 'static,
Returns a predicate that represents the logical OR of this predicate and another.
This method consumes self due to single-ownership semantics.
§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 - Another
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new BoxPredicate representing the logical OR.
§Examples
§Combining with closures
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
let is_large = |x: &i32| *x > 100;
// Note: is_negative is moved here, so it's no longer usable
let combined = is_negative.or(is_large);
assert!(combined.test(&-5)); // negative
assert!(combined.test(&150)); // greater than 100
assert!(!combined.test(&50)); // neither negative nor greater than 100
// is_negative.test(&-10); // This would not compile - is_negative was moved§Combining with function pointers
use prism3_function::predicate::{Predicate, BoxPredicate};
fn is_large(x: &i32) -> bool { *x > 100 }
let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
let combined = is_negative.or(is_large);
assert!(combined.test(&-5));
assert!(combined.test(&150));§Combining with other BoxPredicate
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
let is_large = BoxPredicate::new(|x: &i32| *x > 100);
let combined = is_negative.or(is_large);
assert!(combined.test(&-5));
assert!(combined.test(&150));§Preserving original predicates with clone
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
let is_large = BoxPredicate::new(|x: &i32| *x > 100);
// Clone the predicates to preserve them for later use
let combined = is_negative.clone().or(is_large.clone());
assert!(combined.test(&-5));
assert!(combined.test(&150));
// Original predicates are still usable
assert!(is_negative.test(&-10));
assert!(is_large.test(&200));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 not(self) -> BoxPredicate<T>
pub fn not(self) -> BoxPredicate<T>
Returns a predicate that represents the logical negation of this predicate.
This method consumes self due to single-ownership semantics.
§Returns
A new BoxPredicate representing the logical negation.
Sourcepub fn nand<P>(self, other: P) -> BoxPredicate<T>where
P: Predicate<T> + 'static,
pub fn nand<P>(self, other: P) -> BoxPredicate<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).
This method consumes self due to single-ownership semantics.
§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 - Another
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new BoxPredicate representing the logical NAND.
§Examples
§Combining with closures
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
// Note: is_positive is moved here, so it's no longer usable
let nand = is_positive.nand(is_even);
assert!(nand.test(&3)); // positive but odd: !(true && false) = true
assert!(nand.test(&-2)); // even but negative: !(false && true) = true
assert!(!nand.test(&4)); // positive and even: !(true && true) = false
// is_positive.test(&5); // This would not compile - is_positive was moved§Combining with function pointers
use prism3_function::predicate::{Predicate, BoxPredicate};
fn is_even(x: &i32) -> bool { x % 2 == 0 }
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let nand = is_positive.nand(is_even);
assert!(nand.test(&3));
assert!(!nand.test(&4));§Combining with other BoxPredicate
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
let nand = is_positive.nand(is_even);
assert!(nand.test(&3)); // returns true when only one condition is met
assert!(!nand.test(&4)); // returns false when both conditions are met§Preserving original predicates with clone
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
// Clone the predicates to preserve them for later use
let nand = is_positive.clone().nand(is_even.clone());
assert!(nand.test(&3)); // returns true when only one condition is met
assert!(!nand.test(&4)); // returns false when both conditions are met
// Original predicates are still usable
assert!(is_positive.test(&5));
assert!(is_even.test(&6));Sourcepub fn xor<P>(self, other: P) -> BoxPredicate<T>where
P: Predicate<T> + 'static,
pub fn xor<P>(self, other: P) -> BoxPredicate<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.
This method consumes self due to single-ownership semantics.
§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 - Another
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new BoxPredicate representing the logical XOR.
§Examples
§Combining with closures
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
// Note: is_positive is moved here, so it's no longer usable
let xor = is_positive.xor(is_even);
assert!(xor.test(&3)); // positive but odd: true ^ false = true
assert!(xor.test(&-2)); // even but negative: false ^ true = true
assert!(!xor.test(&4)); // positive and even: true ^ true = false
assert!(!xor.test(&-1)); // negative and odd: false ^ false = false
// is_positive.test(&5); // This would not compile - is_positive was moved§Combining with function pointers
use prism3_function::predicate::{Predicate, BoxPredicate};
fn is_even(x: &i32) -> bool { x % 2 == 0 }
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let xor = is_positive.xor(is_even);
assert!(xor.test(&3));
assert!(!xor.test(&4));§Combining with other BoxPredicate
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
let xor = is_positive.xor(is_even);
assert!(xor.test(&3)); // returns true when only one condition is met
assert!(!xor.test(&4)); // returns false when both conditions are met
assert!(!xor.test(&-1)); // returns false when neither condition is met§Preserving original predicates with clone
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
// Clone the predicates to preserve them for later use
let xor = is_positive.clone().xor(is_even.clone());
assert!(xor.test(&3)); // returns true when only one condition is met
assert!(!xor.test(&4)); // returns false when both conditions are met
assert!(!xor.test(&-1)); // returns false when neither condition is met
// Original predicates are still usable
assert!(is_positive.test(&5));
assert!(is_even.test(&6));Sourcepub fn nor<P>(self, other: P) -> BoxPredicate<T>where
P: Predicate<T> + 'static,
pub fn nor<P>(self, other: P) -> BoxPredicate<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).
This method consumes self due to single-ownership semantics.
§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 - Another
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
A new BoxPredicate representing the logical NOR.
§Examples
§Combining with closures
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;
// Note: is_positive is moved here, so it's no longer usable
let nor = is_positive.nor(is_even);
assert!(nor.test(&-3)); // Neither positive nor even:
// !(false || false) = true
assert!(!nor.test(&4)); // Both positive and even:
// !(true || true) = false
assert!(!nor.test(&3)); // Positive but not even:
// !(true || false) = false
assert!(!nor.test(&-2)); // Even but not positive:
// !(false || true) = false
// is_positive.test(&5); // This would not compile - is_positive was moved§Combining with function pointers
use prism3_function::predicate::{Predicate, BoxPredicate};
fn is_even(x: &i32) -> bool { x % 2 == 0 }
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let nor = is_positive.nor(is_even);
assert!(nor.test(&-3));
assert!(!nor.test(&4));§Combining with other BoxPredicate
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
let nor = is_positive.nor(is_even);
assert!(nor.test(&-3)); // Returns true only when both are false
assert!(!nor.test(&4)); // Returns false when at least one is true§Preserving original predicates with clone
use prism3_function::predicate::{Predicate, BoxPredicate};
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
// Clone the predicates to preserve them for later use
let nor = is_positive.clone().nor(is_even.clone());
assert!(nor.test(&-3)); // Returns true only when both are false
assert!(!nor.test(&4)); // Returns false when at least one is true
// Original predicates are still usable
assert!(is_positive.test(&5));
assert!(is_even.test(&6));Trait Implementations§
Source§impl<T> Debug for BoxPredicate<T>
impl<T> Debug for BoxPredicate<T>
Source§impl<T> Display for BoxPredicate<T>
impl<T> Display for BoxPredicate<T>
Source§impl<T: 'static> Predicate<T> for BoxPredicate<T>
impl<T: 'static> Predicate<T> for BoxPredicate<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 more