Skip to main content

ArcPredicate

Struct ArcPredicate 

Source
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();

§Author

Haixing Hu

Implementations§

Source§

impl<T> ArcPredicate<T>

Source

pub fn new<F>(f: F) -> Self
where F: Fn(&T) -> bool + Send + Sync + 'static,

Creates a new predicate.

Wraps the provided closure in the appropriate smart pointer type for this predicate implementation.

Examples found in repository?
examples/predicates/predicate_fn_mut_demo.rs (line 88)
85fn demo_thread_safe() {
86    println!("4. Thread-safe usage");
87
88    let pred = ArcPredicate::new(|x: &i32| *x > 0);
89    // clone and convert into a 'static closure so it can be moved to another thread
90    let closure = pred.clone().into_fn();
91
92    // Closure can be passed between threads
93    let handle = std::thread::spawn(move || {
94        let numbers = [-2, -1, 0, 1, 2, 3];
95        numbers.iter().copied().filter(closure).count()
96    });
97
98    let count = handle.join().unwrap();
99    println!("   Filtered result count in thread: {}", count);
100    assert_eq!(count, 3);
101
102    // Original predicate is still available
103    assert!(pred.test(&5));
104    println!("   ✓ ArcPredicate::to_fn() returns a thread-safe closure");
105    println!("   ✓ Original predicate is still available in main thread\n");
106}
More examples
Hide additional examples
examples/predicates/predicate_demo.rs (line 140)
137fn arc_predicate_examples() {
138    println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
139
140    let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
141    let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
142
143    // Create combined predicate
144    let combined = is_positive.and(is_even);
145
146    // Use in multiple threads
147    let handles: Vec<_> = (0..3)
148        .map(|i| {
149            let pred = combined.clone();
150            std::thread::spawn(move || {
151                let value = i * 2;
152                println!("  Thread {} testing {}: {}", i, value, pred.test(&value));
153            })
154        })
155        .collect();
156
157    for handle in handles {
158        handle.join().unwrap();
159    }
160
161    // Original predicates still usable
162    println!("Original predicates still available in main thread:");
163    println!("  is_positive.test(&5) = {}", is_positive.test(&5));
164}
165
166/// Logical composition examples
167fn logical_composition_examples() {
168    println!("--- 5. Logical Composition Examples ---");
169
170    let positive = RcPredicate::new_with_name("positive", |x: &i32| *x > 0);
171    let even = RcPredicate::new_with_name("even", |x: &i32| x % 2 == 0);
172    let less_than_ten = RcPredicate::new_with_name("less_than_ten", |x: &i32| *x < 10);
173
174    // AND composition
175    let positive_and_even = positive.and(even.clone());
176    println!("positive AND even: name={:?}", positive_and_even.name());
177    println!("  Test 4: {}", positive_and_even.test(&4));
178    println!("  Test 5: {}", positive_and_even.test(&5));
179
180    // OR composition
181    let positive_or_even = positive.or(even.clone());
182    println!("positive OR even: name={:?}", positive_or_even.name());
183    println!("  Test -2: {}", positive_or_even.test(&-2));
184    println!("  Test 5: {}", positive_or_even.test(&5));
185
186    // NOT composition
187    let not_positive = positive.not();
188    println!("NOT positive: name={:?}", not_positive.name());
189    println!("  Test 5: {}", not_positive.test(&5));
190    println!("  Test -3: {}", not_positive.test(&-3));
191
192    // NAND composition
193    let nand = positive.nand(even.clone());
194    println!("positive NAND even: name={:?}", nand.name());
195    println!("  Test 3: {}", nand.test(&3)); // true NAND false = true
196    println!("  Test 4: {}", nand.test(&4)); // true NAND true = false
197
198    // XOR composition
199    let xor = positive.xor(even.clone());
200    println!("positive XOR even: name={:?}", xor.name());
201    println!("  Test 3: {}", xor.test(&3)); // true XOR false = true
202    println!("  Test 4: {}", xor.test(&4)); // true XOR true = false
203    println!("  Test -2: {}", xor.test(&-2)); // false XOR true = true
204
205    // NOR composition
206    let nor = positive.nor(even.clone());
207    println!("positive NOR even: name={:?}", nor.name());
208    println!("  Test -3: {}", nor.test(&-3)); // false NOR false = true
209    println!("  Test 3: {}", nor.test(&3)); // true NOR false = false
210    println!("  Test -2: {}", nor.test(&-2)); // false NOR true = false
211    println!("  Test 4: {}", nor.test(&4)); // true NOR true = false
212
213    // Complex composition
214    let complex = positive.and(even.clone()).and(less_than_ten.clone());
215    println!("Complex composition: name={:?}", complex.name());
216    println!("  Test 4: {}", complex.test(&4));
217    println!("  Test 12: {}", complex.test(&12));
218}
219
220/// Interior mutability examples
221fn interior_mutability_examples() {
222    println!("--- 6. Interior Mutability Examples ---");
223
224    // BoxPredicate with counter (RefCell)
225    println!("BoxPredicate with counter:");
226    let count = RefCell::new(0);
227    let pred = BoxPredicate::new(move |x: &i32| {
228        *count.borrow_mut() += 1;
229        *x > 0
230    });
231    println!("  Test 5: {}", pred.test(&5));
232    println!("  Test -3: {}", pred.test(&-3));
233    println!("  Test 10: {}", pred.test(&10));
234    // Note: count is moved into the closure, so we can't access it here
235
236    // RcPredicate with cache (RefCell + HashMap)
237    println!("\nRcPredicate with cache:");
238    let cache: RefCell<HashMap<i32, bool>> = RefCell::new(HashMap::new());
239    let expensive_pred = RcPredicate::new(move |x: &i32| {
240        let mut c = cache.borrow_mut();
241        *c.entry(*x).or_insert_with(|| {
242            println!("    Computing result for {} (expensive operation)", x);
243            *x > 0 && x % 2 == 0
244        })
245    });
246
247    println!("  First test 4:");
248    println!("    Result: {}", expensive_pred.test(&4));
249    println!("  Test 4 again (using cache):");
250    println!("    Result: {}", expensive_pred.test(&4));
251    println!("  Test 3:");
252    println!("    Result: {}", expensive_pred.test(&3));
253
254    // ArcPredicate with thread-safe counter (Mutex)
255    println!("\nArcPredicate with thread-safe counter:");
256    let counter = Arc::new(Mutex::new(0));
257    let pred = ArcPredicate::new({
258        let counter = Arc::clone(&counter);
259        move |x: &i32| {
260            let mut c = counter.lock().unwrap();
261            *c += 1;
262            *x > 0
263        }
264    });
265
266    let pred_clone = pred.clone();
267    let counter_clone = Arc::clone(&counter);
268
269    let handle = std::thread::spawn(move || {
270        pred_clone.test(&5);
271        pred_clone.test(&10);
272    });
273
274    pred.test(&3);
275    handle.join().unwrap();
276
277    println!("  Total call count: {}", counter_clone.lock().unwrap());
278}
examples/predicates/predicate_set_name_demo.rs (line 92)
80fn demo_arc_predicate() {
81    println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
82
83    // Using new_with_name
84    let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
85        s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
86    });
87    println!("   Using new_with_name:");
88    println!("     Name: {:?}", pred1.name());
89    println!("     Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
90
91    // Using set_name
92    let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
93    println!("\n   Using set_name:");
94    println!("     Initial name: {:?}", pred2.name());
95    pred2.set_name("longer_than_5");
96    println!("     Name after setting: {:?}", pred2.name());
97    println!(
98        "     Test 'Hello World': {}",
99        pred2.test(&"Hello World".to_string())
100    );
101
102    // Name is preserved when sharing between threads
103    let pred3 = pred2.clone();
104    let handle = std::thread::spawn(move || {
105        let name = pred3.name().map(str::to_string);
106        let result = pred3.test(&"Threading".to_string());
107        (name, result)
108    });
109
110    let (name, result) = handle.join().unwrap();
111    println!("\n   Accessing from thread:");
112    println!("     Name in thread: {:?}", name);
113    println!("     Test 'Threading' in thread: {}", result);
114
115    // Original predicate is still available
116    println!("\n   Original predicate still available:");
117    println!("     Original name: {:?}", pred2.name());
118    println!("     Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
119}
Source

pub fn new_with_name<F>(name: &str, f: F) -> Self
where F: Fn(&T) -> bool + Send + Sync + 'static,

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?
examples/predicates/predicate_set_name_demo.rs (lines 84-86)
80fn demo_arc_predicate() {
81    println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
82
83    // Using new_with_name
84    let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
85        s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
86    });
87    println!("   Using new_with_name:");
88    println!("     Name: {:?}", pred1.name());
89    println!("     Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
90
91    // Using set_name
92    let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
93    println!("\n   Using set_name:");
94    println!("     Initial name: {:?}", pred2.name());
95    pred2.set_name("longer_than_5");
96    println!("     Name after setting: {:?}", pred2.name());
97    println!(
98        "     Test 'Hello World': {}",
99        pred2.test(&"Hello World".to_string())
100    );
101
102    // Name is preserved when sharing between threads
103    let pred3 = pred2.clone();
104    let handle = std::thread::spawn(move || {
105        let name = pred3.name().map(str::to_string);
106        let result = pred3.test(&"Threading".to_string());
107        (name, result)
108    });
109
110    let (name, result) = handle.join().unwrap();
111    println!("\n   Accessing from thread:");
112    println!("     Name in thread: {:?}", name);
113    println!("     Test 'Threading' in thread: {}", result);
114
115    // Original predicate is still available
116    println!("\n   Original predicate still available:");
117    println!("     Original name: {:?}", pred2.name());
118    println!("     Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
119}
Source

pub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
where F: Fn(&T) -> bool + Send + Sync + 'static,

Creates a new named predicate with an optional name.

Wraps the provided closure and assigns it an optional name.

Source

pub fn name(&self) -> Option<&str>

Gets the name of this predicate.

§Returns

Returns Some(&str) if a name was set, None otherwise.

Examples found in repository?
examples/predicates/predicate_set_name_demo.rs (line 88)
80fn demo_arc_predicate() {
81    println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
82
83    // Using new_with_name
84    let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
85        s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
86    });
87    println!("   Using new_with_name:");
88    println!("     Name: {:?}", pred1.name());
89    println!("     Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
90
91    // Using set_name
92    let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
93    println!("\n   Using set_name:");
94    println!("     Initial name: {:?}", pred2.name());
95    pred2.set_name("longer_than_5");
96    println!("     Name after setting: {:?}", pred2.name());
97    println!(
98        "     Test 'Hello World': {}",
99        pred2.test(&"Hello World".to_string())
100    );
101
102    // Name is preserved when sharing between threads
103    let pred3 = pred2.clone();
104    let handle = std::thread::spawn(move || {
105        let name = pred3.name().map(str::to_string);
106        let result = pred3.test(&"Threading".to_string());
107        (name, result)
108    });
109
110    let (name, result) = handle.join().unwrap();
111    println!("\n   Accessing from thread:");
112    println!("     Name in thread: {:?}", name);
113    println!("     Test 'Threading' in thread: {}", result);
114
115    // Original predicate is still available
116    println!("\n   Original predicate still available:");
117    println!("     Original name: {:?}", pred2.name());
118    println!("     Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
119}
More examples
Hide additional examples
examples/predicates/always_predicate_demo.rs (line 82)
16fn main() {
17    println!("=== BoxPredicate always_true/always_false Demo ===\n");
18
19    // BoxPredicate::always_true
20    let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
21    println!("BoxPredicate::always_true():");
22    println!("  test(&42): {}", always_true.test(&42));
23    println!("  test(&-1): {}", always_true.test(&-1));
24    println!("  test(&0): {}", always_true.test(&0));
25    println!("  name: {:?}", always_true.name());
26
27    // BoxPredicate::always_false
28    let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
29    println!("\nBoxPredicate::always_false():");
30    println!("  test(&42): {}", always_false.test(&42));
31    println!("  test(&-1): {}", always_false.test(&-1));
32    println!("  test(&0): {}", always_false.test(&0));
33    println!("  name: {:?}", always_false.name());
34
35    println!("\n=== RcPredicate always_true/always_false Demo ===\n");
36
37    // RcPredicate::always_true
38    let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
39    println!("RcPredicate::always_true():");
40    println!(
41        "  test(&\"hello\"): {}",
42        rc_always_true.test(&"hello".to_string())
43    );
44    println!(
45        "  test(&\"world\"): {}",
46        rc_always_true.test(&"world".to_string())
47    );
48    println!("  name: {:?}", rc_always_true.name());
49
50    // RcPredicate::always_false
51    let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
52    println!("\nRcPredicate::always_false():");
53    println!(
54        "  test(&\"hello\"): {}",
55        rc_always_false.test(&"hello".to_string())
56    );
57    println!(
58        "  test(&\"world\"): {}",
59        rc_always_false.test(&"world".to_string())
60    );
61    println!("  name: {:?}", rc_always_false.name());
62
63    // Can be cloned and reused
64    let rc_clone = rc_always_true.clone();
65    println!("\nAfter cloning, still usable:");
66    println!(
67        "  Original: test(&\"test\"): {}",
68        rc_always_true.test(&"test".to_string())
69    );
70    println!(
71        "  Clone: test(&\"test\"): {}",
72        rc_clone.test(&"test".to_string())
73    );
74
75    println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
76
77    // ArcPredicate::always_true
78    let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
79    println!("ArcPredicate::always_true():");
80    println!("  test(&100): {}", arc_always_true.test(&100));
81    println!("  test(&-100): {}", arc_always_true.test(&-100));
82    println!("  name: {:?}", arc_always_true.name());
83
84    // ArcPredicate::always_false
85    let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
86    println!("\nArcPredicate::always_false():");
87    println!("  test(&100): {}", arc_always_false.test(&100));
88    println!("  test(&-100): {}", arc_always_false.test(&-100));
89    println!("  name: {:?}", arc_always_false.name());
90
91    println!("\n=== Combining with other predicates ===\n");
92
93    // Combining with always_true (AND)
94    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
95    let combined_and_true = is_positive.and(BoxPredicate::always_true());
96    println!("is_positive AND always_true:");
97    println!(
98        "  test(&5): {} (equivalent to is_positive)",
99        combined_and_true.test(&5)
100    );
101    println!(
102        "  test(&-3): {} (equivalent to is_positive)",
103        combined_and_true.test(&-3)
104    );
105
106    // Combining with always_false (AND)
107    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
108    let combined_and_false = is_positive.and(BoxPredicate::always_false());
109    println!("\nis_positive AND always_false:");
110    println!("  test(&5): {} (always false)", combined_and_false.test(&5));
111    println!(
112        "  test(&-3): {} (always false)",
113        combined_and_false.test(&-3)
114    );
115
116    // Combining with always_true (OR)
117    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
118    let combined_or_true = is_positive.or(BoxPredicate::always_true());
119    println!("\nis_positive OR always_true:");
120    println!("  test(&5): {} (always true)", combined_or_true.test(&5));
121    println!("  test(&-3): {} (always true)", combined_or_true.test(&-3));
122
123    // Combining with always_false (OR)
124    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
125    let combined_or_false = is_positive.or(BoxPredicate::always_false());
126    println!("\nis_positive OR always_false:");
127    println!(
128        "  test(&5): {} (equivalent to is_positive)",
129        combined_or_false.test(&5)
130    );
131    println!(
132        "  test(&-3): {} (equivalent to is_positive)",
133        combined_or_false.test(&-3)
134    );
135
136    println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
137
138    // Scenario 1: Default pass-all filter
139    let numbers = vec![1, 2, 3, 4, 5];
140    let pass_all = BoxPredicate::<i32>::always_true();
141    let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
142    println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
143
144    // Scenario 2: Default reject-all filter
145    let numbers = vec![1, 2, 3, 4, 5];
146    let reject_all = BoxPredicate::<i32>::always_false();
147    let filtered: Vec<_> = numbers
148        .iter()
149        .copied()
150        .filter(reject_all.into_fn())
151        .collect();
152    println!(
153        "Default reject all elements: {:?} -> {:?}",
154        numbers, filtered
155    );
156
157    // Scenario 3: Configurable filter
158    fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
159        if enable_filter {
160            BoxPredicate::new(|x: &i32| *x > 3)
161        } else {
162            BoxPredicate::always_true()
163        }
164    }
165
166    let numbers = vec![1, 2, 3, 4, 5];
167
168    let filter_enabled = configurable_filter(true);
169    let filtered: Vec<_> = numbers
170        .iter()
171        .copied()
172        .filter(filter_enabled.into_fn())
173        .collect();
174    println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
175
176    let filter_disabled = configurable_filter(false);
177    let filtered: Vec<_> = numbers
178        .iter()
179        .copied()
180        .filter(filter_disabled.into_fn())
181        .collect();
182    println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
183}
Source

pub fn set_name(&mut self, name: &str)

Sets the name of this predicate.

§Parameters
  • name - The name to set for this predicate
Examples found in repository?
examples/predicates/predicate_set_name_demo.rs (line 95)
80fn demo_arc_predicate() {
81    println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
82
83    // Using new_with_name
84    let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
85        s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
86    });
87    println!("   Using new_with_name:");
88    println!("     Name: {:?}", pred1.name());
89    println!("     Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
90
91    // Using set_name
92    let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
93    println!("\n   Using set_name:");
94    println!("     Initial name: {:?}", pred2.name());
95    pred2.set_name("longer_than_5");
96    println!("     Name after setting: {:?}", pred2.name());
97    println!(
98        "     Test 'Hello World': {}",
99        pred2.test(&"Hello World".to_string())
100    );
101
102    // Name is preserved when sharing between threads
103    let pred3 = pred2.clone();
104    let handle = std::thread::spawn(move || {
105        let name = pred3.name().map(str::to_string);
106        let result = pred3.test(&"Threading".to_string());
107        (name, result)
108    });
109
110    let (name, result) = handle.join().unwrap();
111    println!("\n   Accessing from thread:");
112    println!("     Name in thread: {:?}", name);
113    println!("     Test 'Threading' in thread: {}", result);
114
115    // Original predicate is still available
116    println!("\n   Original predicate still available:");
117    println!("     Original name: {:?}", pred2.name());
118    println!("     Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
119}
Source

pub fn clear_name(&mut self)

Clears the name of this predicate.

Source

pub fn always_true() -> Self

Creates a predicate that always returns true.

§Returns

A new ArcPredicate that always returns true.

Examples found in repository?
examples/predicates/always_predicate_demo.rs (line 78)
16fn main() {
17    println!("=== BoxPredicate always_true/always_false Demo ===\n");
18
19    // BoxPredicate::always_true
20    let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
21    println!("BoxPredicate::always_true():");
22    println!("  test(&42): {}", always_true.test(&42));
23    println!("  test(&-1): {}", always_true.test(&-1));
24    println!("  test(&0): {}", always_true.test(&0));
25    println!("  name: {:?}", always_true.name());
26
27    // BoxPredicate::always_false
28    let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
29    println!("\nBoxPredicate::always_false():");
30    println!("  test(&42): {}", always_false.test(&42));
31    println!("  test(&-1): {}", always_false.test(&-1));
32    println!("  test(&0): {}", always_false.test(&0));
33    println!("  name: {:?}", always_false.name());
34
35    println!("\n=== RcPredicate always_true/always_false Demo ===\n");
36
37    // RcPredicate::always_true
38    let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
39    println!("RcPredicate::always_true():");
40    println!(
41        "  test(&\"hello\"): {}",
42        rc_always_true.test(&"hello".to_string())
43    );
44    println!(
45        "  test(&\"world\"): {}",
46        rc_always_true.test(&"world".to_string())
47    );
48    println!("  name: {:?}", rc_always_true.name());
49
50    // RcPredicate::always_false
51    let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
52    println!("\nRcPredicate::always_false():");
53    println!(
54        "  test(&\"hello\"): {}",
55        rc_always_false.test(&"hello".to_string())
56    );
57    println!(
58        "  test(&\"world\"): {}",
59        rc_always_false.test(&"world".to_string())
60    );
61    println!("  name: {:?}", rc_always_false.name());
62
63    // Can be cloned and reused
64    let rc_clone = rc_always_true.clone();
65    println!("\nAfter cloning, still usable:");
66    println!(
67        "  Original: test(&\"test\"): {}",
68        rc_always_true.test(&"test".to_string())
69    );
70    println!(
71        "  Clone: test(&\"test\"): {}",
72        rc_clone.test(&"test".to_string())
73    );
74
75    println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
76
77    // ArcPredicate::always_true
78    let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
79    println!("ArcPredicate::always_true():");
80    println!("  test(&100): {}", arc_always_true.test(&100));
81    println!("  test(&-100): {}", arc_always_true.test(&-100));
82    println!("  name: {:?}", arc_always_true.name());
83
84    // ArcPredicate::always_false
85    let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
86    println!("\nArcPredicate::always_false():");
87    println!("  test(&100): {}", arc_always_false.test(&100));
88    println!("  test(&-100): {}", arc_always_false.test(&-100));
89    println!("  name: {:?}", arc_always_false.name());
90
91    println!("\n=== Combining with other predicates ===\n");
92
93    // Combining with always_true (AND)
94    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
95    let combined_and_true = is_positive.and(BoxPredicate::always_true());
96    println!("is_positive AND always_true:");
97    println!(
98        "  test(&5): {} (equivalent to is_positive)",
99        combined_and_true.test(&5)
100    );
101    println!(
102        "  test(&-3): {} (equivalent to is_positive)",
103        combined_and_true.test(&-3)
104    );
105
106    // Combining with always_false (AND)
107    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
108    let combined_and_false = is_positive.and(BoxPredicate::always_false());
109    println!("\nis_positive AND always_false:");
110    println!("  test(&5): {} (always false)", combined_and_false.test(&5));
111    println!(
112        "  test(&-3): {} (always false)",
113        combined_and_false.test(&-3)
114    );
115
116    // Combining with always_true (OR)
117    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
118    let combined_or_true = is_positive.or(BoxPredicate::always_true());
119    println!("\nis_positive OR always_true:");
120    println!("  test(&5): {} (always true)", combined_or_true.test(&5));
121    println!("  test(&-3): {} (always true)", combined_or_true.test(&-3));
122
123    // Combining with always_false (OR)
124    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
125    let combined_or_false = is_positive.or(BoxPredicate::always_false());
126    println!("\nis_positive OR always_false:");
127    println!(
128        "  test(&5): {} (equivalent to is_positive)",
129        combined_or_false.test(&5)
130    );
131    println!(
132        "  test(&-3): {} (equivalent to is_positive)",
133        combined_or_false.test(&-3)
134    );
135
136    println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
137
138    // Scenario 1: Default pass-all filter
139    let numbers = vec![1, 2, 3, 4, 5];
140    let pass_all = BoxPredicate::<i32>::always_true();
141    let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
142    println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
143
144    // Scenario 2: Default reject-all filter
145    let numbers = vec![1, 2, 3, 4, 5];
146    let reject_all = BoxPredicate::<i32>::always_false();
147    let filtered: Vec<_> = numbers
148        .iter()
149        .copied()
150        .filter(reject_all.into_fn())
151        .collect();
152    println!(
153        "Default reject all elements: {:?} -> {:?}",
154        numbers, filtered
155    );
156
157    // Scenario 3: Configurable filter
158    fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
159        if enable_filter {
160            BoxPredicate::new(|x: &i32| *x > 3)
161        } else {
162            BoxPredicate::always_true()
163        }
164    }
165
166    let numbers = vec![1, 2, 3, 4, 5];
167
168    let filter_enabled = configurable_filter(true);
169    let filtered: Vec<_> = numbers
170        .iter()
171        .copied()
172        .filter(filter_enabled.into_fn())
173        .collect();
174    println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
175
176    let filter_disabled = configurable_filter(false);
177    let filtered: Vec<_> = numbers
178        .iter()
179        .copied()
180        .filter(filter_disabled.into_fn())
181        .collect();
182    println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
183}
Source

pub fn always_false() -> Self

Creates a predicate that always returns false.

§Returns

A new ArcPredicate that always returns false.

Examples found in repository?
examples/predicates/always_predicate_demo.rs (line 85)
16fn main() {
17    println!("=== BoxPredicate always_true/always_false Demo ===\n");
18
19    // BoxPredicate::always_true
20    let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
21    println!("BoxPredicate::always_true():");
22    println!("  test(&42): {}", always_true.test(&42));
23    println!("  test(&-1): {}", always_true.test(&-1));
24    println!("  test(&0): {}", always_true.test(&0));
25    println!("  name: {:?}", always_true.name());
26
27    // BoxPredicate::always_false
28    let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
29    println!("\nBoxPredicate::always_false():");
30    println!("  test(&42): {}", always_false.test(&42));
31    println!("  test(&-1): {}", always_false.test(&-1));
32    println!("  test(&0): {}", always_false.test(&0));
33    println!("  name: {:?}", always_false.name());
34
35    println!("\n=== RcPredicate always_true/always_false Demo ===\n");
36
37    // RcPredicate::always_true
38    let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
39    println!("RcPredicate::always_true():");
40    println!(
41        "  test(&\"hello\"): {}",
42        rc_always_true.test(&"hello".to_string())
43    );
44    println!(
45        "  test(&\"world\"): {}",
46        rc_always_true.test(&"world".to_string())
47    );
48    println!("  name: {:?}", rc_always_true.name());
49
50    // RcPredicate::always_false
51    let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
52    println!("\nRcPredicate::always_false():");
53    println!(
54        "  test(&\"hello\"): {}",
55        rc_always_false.test(&"hello".to_string())
56    );
57    println!(
58        "  test(&\"world\"): {}",
59        rc_always_false.test(&"world".to_string())
60    );
61    println!("  name: {:?}", rc_always_false.name());
62
63    // Can be cloned and reused
64    let rc_clone = rc_always_true.clone();
65    println!("\nAfter cloning, still usable:");
66    println!(
67        "  Original: test(&\"test\"): {}",
68        rc_always_true.test(&"test".to_string())
69    );
70    println!(
71        "  Clone: test(&\"test\"): {}",
72        rc_clone.test(&"test".to_string())
73    );
74
75    println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
76
77    // ArcPredicate::always_true
78    let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
79    println!("ArcPredicate::always_true():");
80    println!("  test(&100): {}", arc_always_true.test(&100));
81    println!("  test(&-100): {}", arc_always_true.test(&-100));
82    println!("  name: {:?}", arc_always_true.name());
83
84    // ArcPredicate::always_false
85    let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
86    println!("\nArcPredicate::always_false():");
87    println!("  test(&100): {}", arc_always_false.test(&100));
88    println!("  test(&-100): {}", arc_always_false.test(&-100));
89    println!("  name: {:?}", arc_always_false.name());
90
91    println!("\n=== Combining with other predicates ===\n");
92
93    // Combining with always_true (AND)
94    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
95    let combined_and_true = is_positive.and(BoxPredicate::always_true());
96    println!("is_positive AND always_true:");
97    println!(
98        "  test(&5): {} (equivalent to is_positive)",
99        combined_and_true.test(&5)
100    );
101    println!(
102        "  test(&-3): {} (equivalent to is_positive)",
103        combined_and_true.test(&-3)
104    );
105
106    // Combining with always_false (AND)
107    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
108    let combined_and_false = is_positive.and(BoxPredicate::always_false());
109    println!("\nis_positive AND always_false:");
110    println!("  test(&5): {} (always false)", combined_and_false.test(&5));
111    println!(
112        "  test(&-3): {} (always false)",
113        combined_and_false.test(&-3)
114    );
115
116    // Combining with always_true (OR)
117    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
118    let combined_or_true = is_positive.or(BoxPredicate::always_true());
119    println!("\nis_positive OR always_true:");
120    println!("  test(&5): {} (always true)", combined_or_true.test(&5));
121    println!("  test(&-3): {} (always true)", combined_or_true.test(&-3));
122
123    // Combining with always_false (OR)
124    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
125    let combined_or_false = is_positive.or(BoxPredicate::always_false());
126    println!("\nis_positive OR always_false:");
127    println!(
128        "  test(&5): {} (equivalent to is_positive)",
129        combined_or_false.test(&5)
130    );
131    println!(
132        "  test(&-3): {} (equivalent to is_positive)",
133        combined_or_false.test(&-3)
134    );
135
136    println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
137
138    // Scenario 1: Default pass-all filter
139    let numbers = vec![1, 2, 3, 4, 5];
140    let pass_all = BoxPredicate::<i32>::always_true();
141    let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
142    println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
143
144    // Scenario 2: Default reject-all filter
145    let numbers = vec![1, 2, 3, 4, 5];
146    let reject_all = BoxPredicate::<i32>::always_false();
147    let filtered: Vec<_> = numbers
148        .iter()
149        .copied()
150        .filter(reject_all.into_fn())
151        .collect();
152    println!(
153        "Default reject all elements: {:?} -> {:?}",
154        numbers, filtered
155    );
156
157    // Scenario 3: Configurable filter
158    fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
159        if enable_filter {
160            BoxPredicate::new(|x: &i32| *x > 3)
161        } else {
162            BoxPredicate::always_true()
163        }
164    }
165
166    let numbers = vec![1, 2, 3, 4, 5];
167
168    let filter_enabled = configurable_filter(true);
169    let filtered: Vec<_> = numbers
170        .iter()
171        .copied()
172        .filter(filter_enabled.into_fn())
173        .collect();
174    println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
175
176    let filter_disabled = configurable_filter(false);
177    let filtered: Vec<_> = numbers
178        .iter()
179        .copied()
180        .filter(filter_disabled.into_fn())
181        .collect();
182    println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
183}
Source

pub fn and<P>(&self, other: P) -> ArcPredicate<T>
where T: 'static, P: Predicate<T> + Send + Sync + '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.
§Returns

A new predicate representing the logical AND.

Examples found in repository?
examples/predicates/predicate_demo.rs (line 144)
137fn arc_predicate_examples() {
138    println!("--- 4. ArcPredicate Examples (Multi-threaded Scenarios) ---");
139
140    let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
141    let is_even = ArcPredicate::new(|x: &i32| x % 2 == 0);
142
143    // Create combined predicate
144    let combined = is_positive.and(is_even);
145
146    // Use in multiple threads
147    let handles: Vec<_> = (0..3)
148        .map(|i| {
149            let pred = combined.clone();
150            std::thread::spawn(move || {
151                let value = i * 2;
152                println!("  Thread {} testing {}: {}", i, value, pred.test(&value));
153            })
154        })
155        .collect();
156
157    for handle in handles {
158        handle.join().unwrap();
159    }
160
161    // Original predicates still usable
162    println!("Original predicates still available in main thread:");
163    println!("  is_positive.test(&5) = {}", is_positive.test(&5));
164}
Source

pub fn or<P>(&self, other: P) -> ArcPredicate<T>
where T: 'static, P: Predicate<T> + Send + Sync + '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.
§Returns

A new predicate representing the logical OR.

Source

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.

Source

pub fn nand<P>(&self, other: P) -> ArcPredicate<T>
where T: 'static, P: Predicate<T> + Send + Sync + '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.
§Returns

A new predicate representing the logical NAND.

Source

pub fn xor<P>(&self, other: P) -> ArcPredicate<T>
where T: 'static, P: Predicate<T> + Send + Sync + '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.
§Returns

A new predicate representing the logical XOR.

Source

pub fn nor<P>(&self, other: P) -> ArcPredicate<T>
where T: 'static, P: Predicate<T> + Send + Sync + '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.
§Returns

A new predicate representing the logical NOR.

Trait Implementations§

Source§

impl<T> Clone for ArcPredicate<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> Debug for ArcPredicate<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Display for ArcPredicate<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Predicate<T> for ArcPredicate<T>

Source§

fn test(&self, value: &T) -> bool

Tests whether the given value satisfies this predicate. Read more
Source§

fn into_box(self) -> BoxPredicate<T>
where Self: 'static,

Converts this predicate into a BoxPredicate. Read more
Source§

fn into_rc(self) -> RcPredicate<T>
where Self: 'static,

Converts this predicate into an RcPredicate. Read more
Source§

fn into_arc(self) -> ArcPredicate<T>

Converts this predicate into an ArcPredicate. Read more
Source§

fn into_fn(self) -> impl Fn(&T) -> bool

Converts this predicate into a closure that can be used directly with standard library methods. Read more
Source§

fn to_box(&self) -> BoxPredicate<T>
where Self: 'static,

Converts a reference to this predicate into a BoxPredicate. Read more
Source§

fn to_rc(&self) -> RcPredicate<T>
where Self: 'static,

Converts a reference to this predicate into an RcPredicate. Read more
Source§

fn to_arc(&self) -> ArcPredicate<T>

Converts a reference to this predicate into an ArcPredicate. Read more
Source§

fn to_fn(&self) -> impl Fn(&T) -> bool

Converts a reference to this predicate into a closure that can be used directly with standard library methods. Read more

Auto Trait Implementations§

§

impl<T> Freeze for ArcPredicate<T>

§

impl<T> !RefUnwindSafe for ArcPredicate<T>

§

impl<T> Send for ArcPredicate<T>

§

impl<T> Sync for ArcPredicate<T>

§

impl<T> Unpin for ArcPredicate<T>

§

impl<T> UnsafeUnpin for ArcPredicate<T>

§

impl<T> !UnwindSafe for ArcPredicate<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.