pub struct ArcPredicate<T> { /* private fields */ }Expand description
An Arc-based predicate with thread-safe shared ownership.
This type is suitable for scenarios where the predicate needs to be
shared across threads. Composition methods borrow &self, allowing the
original predicate to remain usable after composition.
§Examples
use qubit_function::{Predicate, ArcPredicate};
let pred = ArcPredicate::new(|x: &i32| *x > 0);
assert!(pred.test(&5));
// Original predicate remains usable after composition
let combined = pred.and(ArcPredicate::new(|x| x % 2 == 0));
assert!(pred.test(&5)); // Still works
// Can be cloned and sent across threads
let pred_clone = pred.clone();
std::thread::spawn(move || {
assert!(pred_clone.test(&10));
}).join().unwrap();Implementations§
Source§impl<T> ArcPredicate<T>
impl<T> ArcPredicate<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?
86fn demo_thread_safe() {
87 println!("4. Thread-safe usage");
88
89 let pred = ArcPredicate::new(|x: &i32| *x > 0);
90 // clone and convert into a 'static closure so it can be moved to another thread
91 let closure = pred.clone().into_fn();
92
93 // Closure can be passed between threads
94 let handle = std::thread::spawn(move || {
95 let numbers = [-2, -1, 0, 1, 2, 3];
96 numbers.iter().copied().filter(closure).count()
97 });
98
99 let count = handle.join().unwrap();
100 println!(" Filtered result count in thread: {}", count);
101 assert_eq!(count, 3);
102
103 // Original predicate is still available
104 assert!(pred.test(&5));
105 println!(" ✓ ArcPredicate::to_fn() returns a thread-safe closure");
106 println!(" ✓ Original predicate is still available in main thread\n");
107}More examples
138fn arc_predicate_examples() {
139 println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
140
141 let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
142 let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
143
144 // Create combined predicate
145 let combined = is_positive.and(is_even);
146
147 // Use in multiple threads
148 let handles: Vec<_> = (0..3)
149 .map(|i| {
150 let pred = combined.clone();
151 std::thread::spawn(move || {
152 let value = i * 2;
153 println!(" Thread {} testing {}: {}", i, value, pred.test(&value));
154 })
155 })
156 .collect();
157
158 for handle in handles {
159 handle.join().unwrap();
160 }
161
162 // Original predicates still usable
163 println!("Original predicates still available in main thread:");
164 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
165}
166
167/// Logical composition examples
168fn logical_composition_examples() {
169 println!("--- 5. Logical Composition Examples ---");
170
171 let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
172 let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
173 let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
174
175 // AND composition
176 let positive_and_even = positive.and(even.clone());
177 println!("positive AND even: name={:?}", positive_and_even.name());
178 println!(" Test 4: {}", positive_and_even.test(&4));
179 println!(" Test 5: {}", positive_and_even.test(&5));
180
181 // OR composition
182 let positive_or_even = positive.or(even.clone());
183 println!("positive OR even: name={:?}", positive_or_even.name());
184 println!(" Test -2: {}", positive_or_even.test(&-2));
185 println!(" Test 5: {}", positive_or_even.test(&5));
186
187 // NOT composition
188 let not_positive = positive.not();
189 println!("NOT positive: name={:?}", not_positive.name());
190 println!(" Test 5: {}", not_positive.test(&5));
191 println!(" Test -3: {}", not_positive.test(&-3));
192
193 // NAND composition
194 let nand = positive.nand(even.clone());
195 println!("positive NAND even: name={:?}", nand.name());
196 println!(" Test 3: {}", nand.test(&3)); // true NAND false = true
197 println!(" Test 4: {}", nand.test(&4)); // true NAND true = false
198
199 // XOR composition
200 let xor = positive.xor(even.clone());
201 println!("positive XOR even: name={:?}", xor.name());
202 println!(" Test 3: {}", xor.test(&3)); // true XOR false = true
203 println!(" Test 4: {}", xor.test(&4)); // true XOR true = false
204 println!(" Test -2: {}", xor.test(&-2)); // false XOR true = true
205
206 // NOR composition
207 let nor = positive.nor(even.clone());
208 println!("positive NOR even: name={:?}", nor.name());
209 println!(" Test -3: {}", nor.test(&-3)); // false NOR false = true
210 println!(" Test 3: {}", nor.test(&3)); // true NOR false = false
211 println!(" Test -2: {}", nor.test(&-2)); // false NOR true = false
212 println!(" Test 4: {}", nor.test(&4)); // true NOR true = false
213
214 // Complex composition
215 let complex = positive.and(even.clone()).and(less_than_ten.clone());
216 println!("Complex composition: name={:?}", complex.name());
217 println!(" Test 4: {}", complex.test(&4));
218 println!(" Test 12: {}", complex.test(&12));
219}
220
221/// Interior mutability examples
222fn interior_mutability_examples() {
223 println!("--- 6. Interior Mutability Examples ---");
224
225 // BoxPredicate with counter (RefCell)
226 println!("BoxPredicate with counter:");
227 let count = RefCell::new(0);
228 let pred = BoxPredicate::new(move |x: &i32| {
229 *count.borrow_mut() += 1;
230 *x > 0
231 });
232 println!(" Test 5: {}", pred.test(&5));
233 println!(" Test -3: {}", pred.test(&-3));
234 println!(" Test 10: {}", pred.test(&10));
235 // Note: count is moved into the closure, so we can't access it here
236
237 // RcPredicate with cache (RefCell + HashMap)
238 println!("\nRcPredicate with cache:");
239 let cache: RefCell<HashMap<i32, bool>> = RefCell::new(HashMap::new());
240 let expensive_pred = RcPredicate::new(move |x: &i32| {
241 let mut c = cache.borrow_mut();
242 *c.entry(*x).or_insert_with(|| {
243 println!(" Computing result for {} (expensive operation)", x);
244 *x > 0 && x % 2 == 0
245 })
246 });
247
248 println!(" First test 4:");
249 println!(" Result: {}", expensive_pred.test(&4));
250 println!(" Test 4 again (using cache):");
251 println!(" Result: {}", expensive_pred.test(&4));
252 println!(" Test 3:");
253 println!(" Result: {}", expensive_pred.test(&3));
254
255 // ArcPredicate with thread-safe counter (Mutex)
256 println!("\nArcPredicate with thread-safe counter:");
257 let counter = Arc::new(Mutex::new(0));
258 let pred = ArcPredicate::new({
259 let counter = Arc::clone(&counter);
260 move |x: &i32| {
261 let mut c = counter.lock().unwrap();
262 *c += 1;
263 *x > 0
264 }
265 });
266
267 let pred_clone = pred.clone();
268 let counter_clone = Arc::clone(&counter);
269
270 let handle = std::thread::spawn(move || {
271 pred_clone.test(&5);
272 pred_clone.test(&10);
273 });
274
275 pred.test(&3);
276 handle.join().unwrap();
277
278 println!(" Total call count: {}", counter_clone.lock().unwrap());
279}81fn demo_arc_predicate() {
82 println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
83
84 // Using new_with_name
85 let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
86 s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
87 });
88 println!(" Using new_with_name:");
89 println!(" Name: {:?}", pred1.name());
90 println!(" Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
91
92 // Using set_name
93 let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
94 println!("\n Using set_name:");
95 println!(" Initial name: {:?}", pred2.name());
96 pred2.set_name("longer_than_5");
97 println!(" Name after setting: {:?}", pred2.name());
98 println!(
99 " Test 'Hello World': {}",
100 pred2.test(&"Hello World".to_string())
101 );
102
103 // Name is preserved when sharing between threads
104 let pred3 = pred2.clone();
105 let handle = std::thread::spawn(move || {
106 let name = pred3.name().map(str::to_string);
107 let result = pred3.test(&"Threading".to_string());
108 (name, result)
109 });
110
111 let (name, result) = handle.join().unwrap();
112 println!("\n Accessing from thread:");
113 println!(" Name in thread: {:?}", name);
114 println!(" Test 'Threading' in thread: {}", result);
115
116 // Original predicate is still available
117 println!("\n Original predicate still available:");
118 println!(" Original name: {:?}", pred2.name());
119 println!(" Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
120}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?
81fn demo_arc_predicate() {
82 println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
83
84 // Using new_with_name
85 let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
86 s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
87 });
88 println!(" Using new_with_name:");
89 println!(" Name: {:?}", pred1.name());
90 println!(" Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
91
92 // Using set_name
93 let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
94 println!("\n Using set_name:");
95 println!(" Initial name: {:?}", pred2.name());
96 pred2.set_name("longer_than_5");
97 println!(" Name after setting: {:?}", pred2.name());
98 println!(
99 " Test 'Hello World': {}",
100 pred2.test(&"Hello World".to_string())
101 );
102
103 // Name is preserved when sharing between threads
104 let pred3 = pred2.clone();
105 let handle = std::thread::spawn(move || {
106 let name = pred3.name().map(str::to_string);
107 let result = pred3.test(&"Threading".to_string());
108 (name, result)
109 });
110
111 let (name, result) = handle.join().unwrap();
112 println!("\n Accessing from thread:");
113 println!(" Name in thread: {:?}", name);
114 println!(" Test 'Threading' in thread: {}", result);
115
116 // Original predicate is still available
117 println!("\n Original predicate still available:");
118 println!(" Original name: {:?}", pred2.name());
119 println!(" Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
120}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?
81fn demo_arc_predicate() {
82 println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
83
84 // Using new_with_name
85 let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
86 s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
87 });
88 println!(" Using new_with_name:");
89 println!(" Name: {:?}", pred1.name());
90 println!(" Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
91
92 // Using set_name
93 let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
94 println!("\n Using set_name:");
95 println!(" Initial name: {:?}", pred2.name());
96 pred2.set_name("longer_than_5");
97 println!(" Name after setting: {:?}", pred2.name());
98 println!(
99 " Test 'Hello World': {}",
100 pred2.test(&"Hello World".to_string())
101 );
102
103 // Name is preserved when sharing between threads
104 let pred3 = pred2.clone();
105 let handle = std::thread::spawn(move || {
106 let name = pred3.name().map(str::to_string);
107 let result = pred3.test(&"Threading".to_string());
108 (name, result)
109 });
110
111 let (name, result) = handle.join().unwrap();
112 println!("\n Accessing from thread:");
113 println!(" Name in thread: {:?}", name);
114 println!(" Test 'Threading' in thread: {}", result);
115
116 // Original predicate is still available
117 println!("\n Original predicate still available:");
118 println!(" Original name: {:?}", pred2.name());
119 println!(" Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
120}More examples
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!(
42 " test(&\"hello\"): {}",
43 rc_always_true.test(&"hello".to_string())
44 );
45 println!(
46 " test(&\"world\"): {}",
47 rc_always_true.test(&"world".to_string())
48 );
49 println!(" name: {:?}", rc_always_true.name());
50
51 // RcPredicate::always_false
52 let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
53 println!("\nRcPredicate::always_false():");
54 println!(
55 " test(&\"hello\"): {}",
56 rc_always_false.test(&"hello".to_string())
57 );
58 println!(
59 " test(&\"world\"): {}",
60 rc_always_false.test(&"world".to_string())
61 );
62 println!(" name: {:?}", rc_always_false.name());
63
64 // Can be cloned and reused
65 let rc_clone = rc_always_true.clone();
66 println!("\nAfter cloning, still usable:");
67 println!(
68 " Original: test(&\"test\"): {}",
69 rc_always_true.test(&"test".to_string())
70 );
71 println!(
72 " Clone: test(&\"test\"): {}",
73 rc_clone.test(&"test".to_string())
74 );
75
76 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
77
78 // ArcPredicate::always_true
79 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
80 println!("ArcPredicate::always_true():");
81 println!(" test(&100): {}", arc_always_true.test(&100));
82 println!(" test(&-100): {}", arc_always_true.test(&-100));
83 println!(" name: {:?}", arc_always_true.name());
84
85 // ArcPredicate::always_false
86 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
87 println!("\nArcPredicate::always_false():");
88 println!(" test(&100): {}", arc_always_false.test(&100));
89 println!(" test(&-100): {}", arc_always_false.test(&-100));
90 println!(" name: {:?}", arc_always_false.name());
91
92 println!("\n=== Combining with other predicates ===\n");
93
94 // Combining with always_true (AND)
95 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
96 let combined_and_true = is_positive.and(BoxPredicate::always_true());
97 println!("is_positive AND always_true:");
98 println!(
99 " test(&5): {} (equivalent to is_positive)",
100 combined_and_true.test(&5)
101 );
102 println!(
103 " test(&-3): {} (equivalent to is_positive)",
104 combined_and_true.test(&-3)
105 );
106
107 // Combining with always_false (AND)
108 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
109 let combined_and_false = is_positive.and(BoxPredicate::always_false());
110 println!("\nis_positive AND always_false:");
111 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
112 println!(
113 " test(&-3): {} (always false)",
114 combined_and_false.test(&-3)
115 );
116
117 // Combining with always_true (OR)
118 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
119 let combined_or_true = is_positive.or(BoxPredicate::always_true());
120 println!("\nis_positive OR always_true:");
121 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
122 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
123
124 // Combining with always_false (OR)
125 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
126 let combined_or_false = is_positive.or(BoxPredicate::always_false());
127 println!("\nis_positive OR always_false:");
128 println!(
129 " test(&5): {} (equivalent to is_positive)",
130 combined_or_false.test(&5)
131 );
132 println!(
133 " test(&-3): {} (equivalent to is_positive)",
134 combined_or_false.test(&-3)
135 );
136
137 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
138
139 // Scenario 1: Default pass-all filter
140 let numbers = vec![1, 2, 3, 4, 5];
141 let pass_all = BoxPredicate::<i32>::always_true();
142 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
143 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
144
145 // Scenario 2: Default reject-all filter
146 let numbers = vec![1, 2, 3, 4, 5];
147 let reject_all = BoxPredicate::<i32>::always_false();
148 let filtered: Vec<_> = numbers
149 .iter()
150 .copied()
151 .filter(reject_all.into_fn())
152 .collect();
153 println!(
154 "Default reject all elements: {:?} -> {:?}",
155 numbers, filtered
156 );
157
158 // Scenario 3: Configurable filter
159 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
160 if enable_filter {
161 BoxPredicate::new(|x: &i32| *x > 3)
162 } else {
163 BoxPredicate::always_true()
164 }
165 }
166
167 let numbers = vec![1, 2, 3, 4, 5];
168
169 let filter_enabled = configurable_filter(true);
170 let filtered: Vec<_> = numbers
171 .iter()
172 .copied()
173 .filter(filter_enabled.into_fn())
174 .collect();
175 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
176
177 let filter_disabled = configurable_filter(false);
178 let filtered: Vec<_> = numbers
179 .iter()
180 .copied()
181 .filter(filter_disabled.into_fn())
182 .collect();
183 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
184}Sourcepub fn set_name(&mut self, name: &str)
pub fn set_name(&mut self, name: &str)
Examples found in repository?
81fn demo_arc_predicate() {
82 println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
83
84 // Using new_with_name
85 let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
86 s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
87 });
88 println!(" Using new_with_name:");
89 println!(" Name: {:?}", pred1.name());
90 println!(" Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
91
92 // Using set_name
93 let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
94 println!("\n Using set_name:");
95 println!(" Initial name: {:?}", pred2.name());
96 pred2.set_name("longer_than_5");
97 println!(" Name after setting: {:?}", pred2.name());
98 println!(
99 " Test 'Hello World': {}",
100 pred2.test(&"Hello World".to_string())
101 );
102
103 // Name is preserved when sharing between threads
104 let pred3 = pred2.clone();
105 let handle = std::thread::spawn(move || {
106 let name = pred3.name().map(str::to_string);
107 let result = pred3.test(&"Threading".to_string());
108 (name, result)
109 });
110
111 let (name, result) = handle.join().unwrap();
112 println!("\n Accessing from thread:");
113 println!(" Name in thread: {:?}", name);
114 println!(" Test 'Threading' in thread: {}", result);
115
116 // Original predicate is still available
117 println!("\n Original predicate still available:");
118 println!(" Original name: {:?}", pred2.name());
119 println!(" Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
120}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!(
42 " test(&\"hello\"): {}",
43 rc_always_true.test(&"hello".to_string())
44 );
45 println!(
46 " test(&\"world\"): {}",
47 rc_always_true.test(&"world".to_string())
48 );
49 println!(" name: {:?}", rc_always_true.name());
50
51 // RcPredicate::always_false
52 let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
53 println!("\nRcPredicate::always_false():");
54 println!(
55 " test(&\"hello\"): {}",
56 rc_always_false.test(&"hello".to_string())
57 );
58 println!(
59 " test(&\"world\"): {}",
60 rc_always_false.test(&"world".to_string())
61 );
62 println!(" name: {:?}", rc_always_false.name());
63
64 // Can be cloned and reused
65 let rc_clone = rc_always_true.clone();
66 println!("\nAfter cloning, still usable:");
67 println!(
68 " Original: test(&\"test\"): {}",
69 rc_always_true.test(&"test".to_string())
70 );
71 println!(
72 " Clone: test(&\"test\"): {}",
73 rc_clone.test(&"test".to_string())
74 );
75
76 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
77
78 // ArcPredicate::always_true
79 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
80 println!("ArcPredicate::always_true():");
81 println!(" test(&100): {}", arc_always_true.test(&100));
82 println!(" test(&-100): {}", arc_always_true.test(&-100));
83 println!(" name: {:?}", arc_always_true.name());
84
85 // ArcPredicate::always_false
86 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
87 println!("\nArcPredicate::always_false():");
88 println!(" test(&100): {}", arc_always_false.test(&100));
89 println!(" test(&-100): {}", arc_always_false.test(&-100));
90 println!(" name: {:?}", arc_always_false.name());
91
92 println!("\n=== Combining with other predicates ===\n");
93
94 // Combining with always_true (AND)
95 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
96 let combined_and_true = is_positive.and(BoxPredicate::always_true());
97 println!("is_positive AND always_true:");
98 println!(
99 " test(&5): {} (equivalent to is_positive)",
100 combined_and_true.test(&5)
101 );
102 println!(
103 " test(&-3): {} (equivalent to is_positive)",
104 combined_and_true.test(&-3)
105 );
106
107 // Combining with always_false (AND)
108 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
109 let combined_and_false = is_positive.and(BoxPredicate::always_false());
110 println!("\nis_positive AND always_false:");
111 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
112 println!(
113 " test(&-3): {} (always false)",
114 combined_and_false.test(&-3)
115 );
116
117 // Combining with always_true (OR)
118 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
119 let combined_or_true = is_positive.or(BoxPredicate::always_true());
120 println!("\nis_positive OR always_true:");
121 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
122 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
123
124 // Combining with always_false (OR)
125 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
126 let combined_or_false = is_positive.or(BoxPredicate::always_false());
127 println!("\nis_positive OR always_false:");
128 println!(
129 " test(&5): {} (equivalent to is_positive)",
130 combined_or_false.test(&5)
131 );
132 println!(
133 " test(&-3): {} (equivalent to is_positive)",
134 combined_or_false.test(&-3)
135 );
136
137 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
138
139 // Scenario 1: Default pass-all filter
140 let numbers = vec![1, 2, 3, 4, 5];
141 let pass_all = BoxPredicate::<i32>::always_true();
142 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
143 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
144
145 // Scenario 2: Default reject-all filter
146 let numbers = vec![1, 2, 3, 4, 5];
147 let reject_all = BoxPredicate::<i32>::always_false();
148 let filtered: Vec<_> = numbers
149 .iter()
150 .copied()
151 .filter(reject_all.into_fn())
152 .collect();
153 println!(
154 "Default reject all elements: {:?} -> {:?}",
155 numbers, filtered
156 );
157
158 // Scenario 3: Configurable filter
159 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
160 if enable_filter {
161 BoxPredicate::new(|x: &i32| *x > 3)
162 } else {
163 BoxPredicate::always_true()
164 }
165 }
166
167 let numbers = vec![1, 2, 3, 4, 5];
168
169 let filter_enabled = configurable_filter(true);
170 let filtered: Vec<_> = numbers
171 .iter()
172 .copied()
173 .filter(filter_enabled.into_fn())
174 .collect();
175 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
176
177 let filter_disabled = configurable_filter(false);
178 let filtered: Vec<_> = numbers
179 .iter()
180 .copied()
181 .filter(filter_disabled.into_fn())
182 .collect();
183 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
184}Sourcepub fn always_false() -> Self
pub fn always_false() -> Self
Creates a predicate that always returns false.
§Returns
A new ArcPredicate 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!(
42 " test(&\"hello\"): {}",
43 rc_always_true.test(&"hello".to_string())
44 );
45 println!(
46 " test(&\"world\"): {}",
47 rc_always_true.test(&"world".to_string())
48 );
49 println!(" name: {:?}", rc_always_true.name());
50
51 // RcPredicate::always_false
52 let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
53 println!("\nRcPredicate::always_false():");
54 println!(
55 " test(&\"hello\"): {}",
56 rc_always_false.test(&"hello".to_string())
57 );
58 println!(
59 " test(&\"world\"): {}",
60 rc_always_false.test(&"world".to_string())
61 );
62 println!(" name: {:?}", rc_always_false.name());
63
64 // Can be cloned and reused
65 let rc_clone = rc_always_true.clone();
66 println!("\nAfter cloning, still usable:");
67 println!(
68 " Original: test(&\"test\"): {}",
69 rc_always_true.test(&"test".to_string())
70 );
71 println!(
72 " Clone: test(&\"test\"): {}",
73 rc_clone.test(&"test".to_string())
74 );
75
76 println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
77
78 // ArcPredicate::always_true
79 let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
80 println!("ArcPredicate::always_true():");
81 println!(" test(&100): {}", arc_always_true.test(&100));
82 println!(" test(&-100): {}", arc_always_true.test(&-100));
83 println!(" name: {:?}", arc_always_true.name());
84
85 // ArcPredicate::always_false
86 let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
87 println!("\nArcPredicate::always_false():");
88 println!(" test(&100): {}", arc_always_false.test(&100));
89 println!(" test(&-100): {}", arc_always_false.test(&-100));
90 println!(" name: {:?}", arc_always_false.name());
91
92 println!("\n=== Combining with other predicates ===\n");
93
94 // Combining with always_true (AND)
95 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
96 let combined_and_true = is_positive.and(BoxPredicate::always_true());
97 println!("is_positive AND always_true:");
98 println!(
99 " test(&5): {} (equivalent to is_positive)",
100 combined_and_true.test(&5)
101 );
102 println!(
103 " test(&-3): {} (equivalent to is_positive)",
104 combined_and_true.test(&-3)
105 );
106
107 // Combining with always_false (AND)
108 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
109 let combined_and_false = is_positive.and(BoxPredicate::always_false());
110 println!("\nis_positive AND always_false:");
111 println!(" test(&5): {} (always false)", combined_and_false.test(&5));
112 println!(
113 " test(&-3): {} (always false)",
114 combined_and_false.test(&-3)
115 );
116
117 // Combining with always_true (OR)
118 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
119 let combined_or_true = is_positive.or(BoxPredicate::always_true());
120 println!("\nis_positive OR always_true:");
121 println!(" test(&5): {} (always true)", combined_or_true.test(&5));
122 println!(" test(&-3): {} (always true)", combined_or_true.test(&-3));
123
124 // Combining with always_false (OR)
125 let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
126 let combined_or_false = is_positive.or(BoxPredicate::always_false());
127 println!("\nis_positive OR always_false:");
128 println!(
129 " test(&5): {} (equivalent to is_positive)",
130 combined_or_false.test(&5)
131 );
132 println!(
133 " test(&-3): {} (equivalent to is_positive)",
134 combined_or_false.test(&-3)
135 );
136
137 println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
138
139 // Scenario 1: Default pass-all filter
140 let numbers = vec![1, 2, 3, 4, 5];
141 let pass_all = BoxPredicate::<i32>::always_true();
142 let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
143 println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
144
145 // Scenario 2: Default reject-all filter
146 let numbers = vec![1, 2, 3, 4, 5];
147 let reject_all = BoxPredicate::<i32>::always_false();
148 let filtered: Vec<_> = numbers
149 .iter()
150 .copied()
151 .filter(reject_all.into_fn())
152 .collect();
153 println!(
154 "Default reject all elements: {:?} -> {:?}",
155 numbers, filtered
156 );
157
158 // Scenario 3: Configurable filter
159 fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
160 if enable_filter {
161 BoxPredicate::new(|x: &i32| *x > 3)
162 } else {
163 BoxPredicate::always_true()
164 }
165 }
166
167 let numbers = vec![1, 2, 3, 4, 5];
168
169 let filter_enabled = configurable_filter(true);
170 let filtered: Vec<_> = numbers
171 .iter()
172 .copied()
173 .filter(filter_enabled.into_fn())
174 .collect();
175 println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
176
177 let filter_disabled = configurable_filter(false);
178 let filtered: Vec<_> = numbers
179 .iter()
180 .copied()
181 .filter(filter_disabled.into_fn())
182 .collect();
183 println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
184}Sourcepub fn and<P>(&self, other: P) -> ArcPredicate<T>
pub fn and<P>(&self, other: P) -> ArcPredicate<T>
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.
§Returns
A new predicate representing the logical AND.
Examples found in repository?
138fn arc_predicate_examples() {
139 println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
140
141 let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
142 let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
143
144 // Create combined predicate
145 let combined = is_positive.and(is_even);
146
147 // Use in multiple threads
148 let handles: Vec<_> = (0..3)
149 .map(|i| {
150 let pred = combined.clone();
151 std::thread::spawn(move || {
152 let value = i * 2;
153 println!(" Thread {} testing {}: {}", i, value, pred.test(&value));
154 })
155 })
156 .collect();
157
158 for handle in handles {
159 handle.join().unwrap();
160 }
161
162 // Original predicates still usable
163 println!("Original predicates still available in main thread:");
164 println!(" is_positive.test(&5) = {}", is_positive.test(&5));
165}Sourcepub fn or<P>(&self, other: P) -> ArcPredicate<T>
pub fn or<P>(&self, other: P) -> ArcPredicate<T>
Sourcepub fn not(&self) -> ArcPredicate<T>where
T: 'static,
pub fn not(&self) -> ArcPredicate<T>where
T: 'static,
Returns a predicate that represents the logical negation of this predicate.
This method consumes self due to single-ownership semantics.
§Returns
A new predicate representing the logical negation.
Sourcepub fn nand<P>(&self, other: P) -> ArcPredicate<T>
pub fn nand<P>(&self, other: P) -> ArcPredicate<T>
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.
§Returns
A new predicate representing the logical NAND.
Sourcepub fn xor<P>(&self, other: P) -> ArcPredicate<T>
pub fn xor<P>(&self, other: P) -> ArcPredicate<T>
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.
§Returns
A new predicate representing the logical XOR.
Sourcepub fn nor<P>(&self, other: P) -> ArcPredicate<T>
pub fn nor<P>(&self, other: P) -> ArcPredicate<T>
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.
§Returns
A new predicate representing the logical NOR.
Trait Implementations§
Source§impl<T> Clone for ArcPredicate<T>
impl<T> Clone for ArcPredicate<T>
Source§impl<T> Debug for ArcPredicate<T>
impl<T> Debug for ArcPredicate<T>
Source§impl<T> Display for ArcPredicate<T>
impl<T> Display for ArcPredicate<T>
Source§impl<T> Predicate<T> for ArcPredicate<T>
impl<T> Predicate<T> for ArcPredicate<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>where
Self: 'static,
fn into_rc(self) -> RcPredicate<T>where
Self: 'static,
RcPredicate. Read moreSource§fn into_arc(self) -> ArcPredicate<T>
fn into_arc(self) -> ArcPredicate<T>
ArcPredicate. 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>where
Self: 'static,
fn to_rc(&self) -> RcPredicate<T>where
Self: 'static,
RcPredicate. Read moreSource§fn to_arc(&self) -> ArcPredicate<T>
fn to_arc(&self) -> ArcPredicate<T>
ArcPredicate. Read more