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 prism3_function::predicate::{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: 'static> ArcPredicate<T>

Source

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

Creates a new ArcPredicate from a closure.

§Parameters
  • f - The closure to wrap.
§Returns

A new ArcPredicate instance.

Examples found in repository?
examples/predicate_fn_mut_demo.rs (line 83)
80fn demo_thread_safe() {
81    println!("4. Thread-safe usage");
82
83    let pred = ArcPredicate::new(|x: &i32| *x > 0);
84    // clone and convert into a 'static closure so it can be moved to another thread
85    let closure = pred.clone().into_fn();
86
87    // Closure can be passed between threads
88    let handle = std::thread::spawn(move || {
89        let numbers = [-2, -1, 0, 1, 2, 3];
90        numbers.iter().copied().filter(closure).count()
91    });
92
93    let count = handle.join().unwrap();
94    println!("   Filtered result count in thread: {}", count);
95    assert_eq!(count, 3);
96
97    // Original predicate is still available
98    assert!(pred.test(&5));
99    println!("   ✓ ArcPredicate::to_fn() returns a thread-safe closure");
100    println!("   ✓ Original predicate is still available in main thread\n");
101}
More examples
Hide additional examples
examples/predicate_demo.rs (line 133)
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}
examples/predicate_set_name_demo.rs (line 87)
75fn demo_arc_predicate() {
76    println!("3. ArcPredicate Naming Functionality (Thread-Safe)");
77
78    // Using new_with_name
79    let pred1 = ArcPredicate::new_with_name("is_uppercase", |s: &String| {
80        s.chars().all(|c| c.is_uppercase() || !c.is_alphabetic())
81    });
82    println!("   Using new_with_name:");
83    println!("     Name: {:?}", pred1.name());
84    println!("     Test 'HELLO': {}", pred1.test(&"HELLO".to_string()));
85
86    // Using set_name
87    let mut pred2 = ArcPredicate::new(|s: &String| s.len() > 5);
88    println!("\n   Using set_name:");
89    println!("     Initial name: {:?}", pred2.name());
90    pred2.set_name("longer_than_5");
91    println!("     Name after setting: {:?}", pred2.name());
92    println!(
93        "     Test 'Hello World': {}",
94        pred2.test(&"Hello World".to_string())
95    );
96
97    // Name is preserved when sharing between threads
98    let pred3 = pred2.clone();
99    let handle = std::thread::spawn(move || {
100        let name = pred3.name().map(|s| s.to_string());
101        let result = pred3.test(&"Threading".to_string());
102        (name, result)
103    });
104
105    let (name, result) = handle.join().unwrap();
106    println!("\n   Accessing from thread:");
107    println!("     Name in thread: {:?}", name);
108    println!("     Test 'Threading' in thread: {}", result);
109
110    // Original predicate is still available
111    println!("\n   Original predicate still available:");
112    println!("     Original name: {:?}", pred2.name());
113    println!("     Test 'Rust': {}\n", pred2.test(&"Rust".to_string()));
114}
Source

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

Creates a named ArcPredicate from a closure.

§Parameters
  • name - The name for this predicate.
  • f - The closure to wrap.
§Returns

A new named ArcPredicate instance.

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

pub fn always_true() -> Self

Creates a predicate that always returns true.

§Returns

A new ArcPredicate that always returns true.

§Examples
use prism3_function::predicate::{Predicate, ArcPredicate};

let pred: ArcPredicate<i32> = ArcPredicate::always_true();
assert!(pred.test(&42));
assert!(pred.test(&-1));
assert!(pred.test(&0));
Examples found in repository?
examples/always_predicate_demo.rs (line 73)
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}
Source

pub fn always_false() -> Self

Creates a predicate that always returns false.

§Returns

A new ArcPredicate that always returns false.

§Examples
use prism3_function::predicate::{Predicate, ArcPredicate};

let pred: ArcPredicate<i32> = ArcPredicate::always_false();
assert!(!pred.test(&42));
assert!(!pred.test(&-1));
assert!(!pred.test(&0));
Examples found in repository?
examples/always_predicate_demo.rs (line 80)
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}
Source

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

Returns the name of this predicate, if set.

§Returns

An Option containing the predicate’s name.

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

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

Sets the name of this predicate.

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

pub fn and<P>(&self, other: P) -> ArcPredicate<T>
where T: Send + Sync, P: Predicate<T> + Send + Sync + 'static,

Returns a predicate that represents the logical AND of this predicate and another.

§Parameters
  • other - The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implements Clone). Can be:
    • A closure: |x: &T| -> bool
    • A function pointer: fn(&T) -> bool
    • A BoxPredicate<T>
    • An RcPredicate<T>
    • Another ArcPredicate<T> (will be moved)
    • Any type implementing Predicate<T> + Send + Sync
§Returns

A new ArcPredicate representing the logical AND.

§Examples
use prism3_function::predicate::{Predicate, ArcPredicate};
use std::thread;

let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;

let combined = is_positive.and(is_even);

// can be used across threads
let handle = thread::spawn(move || {
    combined.test(&4)
});

assert!(handle.join().unwrap());
assert!(is_positive.test(&5)); // original predicate still usable
Examples found in repository?
examples/predicate_demo.rs (line 137)
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}
Source

pub fn or<P>(&self, other: P) -> ArcPredicate<T>
where T: Send + Sync, P: Predicate<T> + Send + Sync + 'static,

Returns a predicate that represents the logical OR of this predicate and another.

§Parameters
  • other - The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implements Clone). Can be:
    • A closure: |x: &T| -> bool
    • A function pointer: fn(&T) -> bool
    • A BoxPredicate<T>
    • An RcPredicate<T>
    • Another ArcPredicate<T> (will be moved)
    • Any type implementing Predicate<T> + Send + Sync
§Returns

A new ArcPredicate representing the logical OR. Thread-safe.

§Examples
use prism3_function::predicate::{Predicate, ArcPredicate};

let is_negative = ArcPredicate::new(|x: &i32| *x < 0);
let is_large = |x: &i32| *x > 100;

let combined = is_negative.or(is_large);
assert!(combined.test(&-5));
assert!(combined.test(&150));
assert!(is_negative.test(&-10)); // original predicate still usable
Source

pub fn not(&self) -> ArcPredicate<T>
where T: Send + Sync,

Returns a predicate that represents the logical negation of this predicate.

§Returns

A new ArcPredicate representing the logical negation.

Source

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

§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 implements Clone). Accepts closures, function pointers, or any Predicate<T> + Send + Sync implementation.
§Returns

A new ArcPredicate representing the logical NAND. Thread-safe.

§Examples
use prism3_function::predicate::{Predicate, ArcPredicate};

let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;

let nand = is_positive.nand(is_even);
assert!(nand.test(&3));   // !(true && false) = true
assert!(!nand.test(&4));  // !(true && true) = false
Source

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

§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 implements Clone).
§Returns

A new ArcPredicate representing the logical XOR.

Source

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

§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 implements Clone). Accepts closures, function pointers, or any Predicate<T> + Send + Sync implementation.
§Returns

A new ArcPredicate representing the logical NOR. Thread-safe.

§Examples
use prism3_function::predicate::{Predicate, ArcPredicate};

let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
let is_even = |x: &i32| x % 2 == 0;

let nor = is_positive.nor(is_even);
assert!(nor.test(&-3));   // !(false || false) = true
assert!(!nor.test(&4));   // !(true || true) = false
assert!(!nor.test(&3));   // !(true || false) = false

Trait Implementations§

Source§

impl<T> Clone for ArcPredicate<T>

Source§

fn clone(&self) -> Self

Clones this predicate.

Creates a new instance that shares the underlying function with the original, allowing multiple references to the same predicate logic.

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

Implements Debug trait for ArcPredicate

Shows the predicate name in debug struct format.

Source§

impl<T> Display for ArcPredicate<T>

Source§

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

Implements Display trait for ArcPredicate

Shows the predicate name if available, or “unnamed” as default.

Source§

impl<T: 'static> 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>

Converts this predicate into a BoxPredicate. Read more
Source§

fn into_rc(self) -> RcPredicate<T>

Converts this predicate into an RcPredicate. Read more
Source§

fn into_arc(self) -> ArcPredicate<T>
where T: Send + Sync,

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>

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

fn to_rc(&self) -> RcPredicate<T>

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> !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.