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>
 
impl<T: 'static> ArcPredicate<T>
Sourcepub fn new<F>(f: F) -> Self
 
pub fn new<F>(f: F) -> Self
Creates a new ArcPredicate from a closure.
§Parameters
f- The closure to wrap.
§Returns
A new ArcPredicate instance.
Examples found in repository?
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
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}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}Sourcepub fn new_with_name<F>(name: &str, f: F) -> Self
 
pub fn new_with_name<F>(name: &str, f: F) -> Self
Creates a named 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?
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}Sourcepub fn always_true() -> Self
 
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?
11fn main() {
12    println!("=== BoxPredicate always_true/always_false Demo ===\n");
13
14    // BoxPredicate::always_true
15    let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
16    println!("BoxPredicate::always_true():");
17    println!("  test(&42): {}", always_true.test(&42));
18    println!("  test(&-1): {}", always_true.test(&-1));
19    println!("  test(&0): {}", always_true.test(&0));
20    println!("  name: {:?}", always_true.name());
21
22    // BoxPredicate::always_false
23    let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
24    println!("\nBoxPredicate::always_false():");
25    println!("  test(&42): {}", always_false.test(&42));
26    println!("  test(&-1): {}", always_false.test(&-1));
27    println!("  test(&0): {}", always_false.test(&0));
28    println!("  name: {:?}", always_false.name());
29
30    println!("\n=== RcPredicate always_true/always_false Demo ===\n");
31
32    // RcPredicate::always_true
33    let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
34    println!("RcPredicate::always_true():");
35    println!(
36        "  test(&\"hello\"): {}",
37        rc_always_true.test(&"hello".to_string())
38    );
39    println!(
40        "  test(&\"world\"): {}",
41        rc_always_true.test(&"world".to_string())
42    );
43    println!("  name: {:?}", rc_always_true.name());
44
45    // RcPredicate::always_false
46    let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
47    println!("\nRcPredicate::always_false():");
48    println!(
49        "  test(&\"hello\"): {}",
50        rc_always_false.test(&"hello".to_string())
51    );
52    println!(
53        "  test(&\"world\"): {}",
54        rc_always_false.test(&"world".to_string())
55    );
56    println!("  name: {:?}", rc_always_false.name());
57
58    // Can be cloned and reused
59    let rc_clone = rc_always_true.clone();
60    println!("\nAfter cloning, still usable:");
61    println!(
62        "  Original: test(&\"test\"): {}",
63        rc_always_true.test(&"test".to_string())
64    );
65    println!(
66        "  Clone: test(&\"test\"): {}",
67        rc_clone.test(&"test".to_string())
68    );
69
70    println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
71
72    // ArcPredicate::always_true
73    let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
74    println!("ArcPredicate::always_true():");
75    println!("  test(&100): {}", arc_always_true.test(&100));
76    println!("  test(&-100): {}", arc_always_true.test(&-100));
77    println!("  name: {:?}", arc_always_true.name());
78
79    // ArcPredicate::always_false
80    let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
81    println!("\nArcPredicate::always_false():");
82    println!("  test(&100): {}", arc_always_false.test(&100));
83    println!("  test(&-100): {}", arc_always_false.test(&-100));
84    println!("  name: {:?}", arc_always_false.name());
85
86    println!("\n=== Combining with other predicates ===\n");
87
88    // Combining with always_true (AND)
89    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
90    let combined_and_true = is_positive.and(BoxPredicate::always_true());
91    println!("is_positive AND always_true:");
92    println!(
93        "  test(&5): {} (equivalent to is_positive)",
94        combined_and_true.test(&5)
95    );
96    println!(
97        "  test(&-3): {} (equivalent to is_positive)",
98        combined_and_true.test(&-3)
99    );
100
101    // Combining with always_false (AND)
102    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
103    let combined_and_false = is_positive.and(BoxPredicate::always_false());
104    println!("\nis_positive AND always_false:");
105    println!("  test(&5): {} (always false)", combined_and_false.test(&5));
106    println!(
107        "  test(&-3): {} (always false)",
108        combined_and_false.test(&-3)
109    );
110
111    // Combining with always_true (OR)
112    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
113    let combined_or_true = is_positive.or(BoxPredicate::always_true());
114    println!("\nis_positive OR always_true:");
115    println!("  test(&5): {} (always true)", combined_or_true.test(&5));
116    println!("  test(&-3): {} (always true)", combined_or_true.test(&-3));
117
118    // Combining with always_false (OR)
119    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
120    let combined_or_false = is_positive.or(BoxPredicate::always_false());
121    println!("\nis_positive OR always_false:");
122    println!(
123        "  test(&5): {} (equivalent to is_positive)",
124        combined_or_false.test(&5)
125    );
126    println!(
127        "  test(&-3): {} (equivalent to is_positive)",
128        combined_or_false.test(&-3)
129    );
130
131    println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
132
133    // Scenario 1: Default pass-all filter
134    let numbers = vec![1, 2, 3, 4, 5];
135    let pass_all = BoxPredicate::<i32>::always_true();
136    let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
137    println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
138
139    // Scenario 2: Default reject-all filter
140    let numbers = vec![1, 2, 3, 4, 5];
141    let reject_all = BoxPredicate::<i32>::always_false();
142    let filtered: Vec<_> = numbers
143        .iter()
144        .copied()
145        .filter(reject_all.into_fn())
146        .collect();
147    println!(
148        "Default reject all elements: {:?} -> {:?}",
149        numbers, filtered
150    );
151
152    // Scenario 3: Configurable filter
153    fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
154        if enable_filter {
155            BoxPredicate::new(|x: &i32| *x > 3)
156        } else {
157            BoxPredicate::always_true()
158        }
159    }
160
161    let numbers = vec![1, 2, 3, 4, 5];
162
163    let filter_enabled = configurable_filter(true);
164    let filtered: Vec<_> = numbers
165        .iter()
166        .copied()
167        .filter(filter_enabled.into_fn())
168        .collect();
169    println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
170
171    let filter_disabled = configurable_filter(false);
172    let filtered: Vec<_> = numbers
173        .iter()
174        .copied()
175        .filter(filter_disabled.into_fn())
176        .collect();
177    println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
178}Sourcepub fn always_false() -> Self
 
pub fn always_false() -> Self
Creates a predicate that always returns false.
§Returns
A new 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?
11fn main() {
12    println!("=== BoxPredicate always_true/always_false Demo ===\n");
13
14    // BoxPredicate::always_true
15    let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
16    println!("BoxPredicate::always_true():");
17    println!("  test(&42): {}", always_true.test(&42));
18    println!("  test(&-1): {}", always_true.test(&-1));
19    println!("  test(&0): {}", always_true.test(&0));
20    println!("  name: {:?}", always_true.name());
21
22    // BoxPredicate::always_false
23    let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
24    println!("\nBoxPredicate::always_false():");
25    println!("  test(&42): {}", always_false.test(&42));
26    println!("  test(&-1): {}", always_false.test(&-1));
27    println!("  test(&0): {}", always_false.test(&0));
28    println!("  name: {:?}", always_false.name());
29
30    println!("\n=== RcPredicate always_true/always_false Demo ===\n");
31
32    // RcPredicate::always_true
33    let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
34    println!("RcPredicate::always_true():");
35    println!(
36        "  test(&\"hello\"): {}",
37        rc_always_true.test(&"hello".to_string())
38    );
39    println!(
40        "  test(&\"world\"): {}",
41        rc_always_true.test(&"world".to_string())
42    );
43    println!("  name: {:?}", rc_always_true.name());
44
45    // RcPredicate::always_false
46    let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
47    println!("\nRcPredicate::always_false():");
48    println!(
49        "  test(&\"hello\"): {}",
50        rc_always_false.test(&"hello".to_string())
51    );
52    println!(
53        "  test(&\"world\"): {}",
54        rc_always_false.test(&"world".to_string())
55    );
56    println!("  name: {:?}", rc_always_false.name());
57
58    // Can be cloned and reused
59    let rc_clone = rc_always_true.clone();
60    println!("\nAfter cloning, still usable:");
61    println!(
62        "  Original: test(&\"test\"): {}",
63        rc_always_true.test(&"test".to_string())
64    );
65    println!(
66        "  Clone: test(&\"test\"): {}",
67        rc_clone.test(&"test".to_string())
68    );
69
70    println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
71
72    // ArcPredicate::always_true
73    let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
74    println!("ArcPredicate::always_true():");
75    println!("  test(&100): {}", arc_always_true.test(&100));
76    println!("  test(&-100): {}", arc_always_true.test(&-100));
77    println!("  name: {:?}", arc_always_true.name());
78
79    // ArcPredicate::always_false
80    let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
81    println!("\nArcPredicate::always_false():");
82    println!("  test(&100): {}", arc_always_false.test(&100));
83    println!("  test(&-100): {}", arc_always_false.test(&-100));
84    println!("  name: {:?}", arc_always_false.name());
85
86    println!("\n=== Combining with other predicates ===\n");
87
88    // Combining with always_true (AND)
89    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
90    let combined_and_true = is_positive.and(BoxPredicate::always_true());
91    println!("is_positive AND always_true:");
92    println!(
93        "  test(&5): {} (equivalent to is_positive)",
94        combined_and_true.test(&5)
95    );
96    println!(
97        "  test(&-3): {} (equivalent to is_positive)",
98        combined_and_true.test(&-3)
99    );
100
101    // Combining with always_false (AND)
102    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
103    let combined_and_false = is_positive.and(BoxPredicate::always_false());
104    println!("\nis_positive AND always_false:");
105    println!("  test(&5): {} (always false)", combined_and_false.test(&5));
106    println!(
107        "  test(&-3): {} (always false)",
108        combined_and_false.test(&-3)
109    );
110
111    // Combining with always_true (OR)
112    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
113    let combined_or_true = is_positive.or(BoxPredicate::always_true());
114    println!("\nis_positive OR always_true:");
115    println!("  test(&5): {} (always true)", combined_or_true.test(&5));
116    println!("  test(&-3): {} (always true)", combined_or_true.test(&-3));
117
118    // Combining with always_false (OR)
119    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
120    let combined_or_false = is_positive.or(BoxPredicate::always_false());
121    println!("\nis_positive OR always_false:");
122    println!(
123        "  test(&5): {} (equivalent to is_positive)",
124        combined_or_false.test(&5)
125    );
126    println!(
127        "  test(&-3): {} (equivalent to is_positive)",
128        combined_or_false.test(&-3)
129    );
130
131    println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
132
133    // Scenario 1: Default pass-all filter
134    let numbers = vec![1, 2, 3, 4, 5];
135    let pass_all = BoxPredicate::<i32>::always_true();
136    let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
137    println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
138
139    // Scenario 2: Default reject-all filter
140    let numbers = vec![1, 2, 3, 4, 5];
141    let reject_all = BoxPredicate::<i32>::always_false();
142    let filtered: Vec<_> = numbers
143        .iter()
144        .copied()
145        .filter(reject_all.into_fn())
146        .collect();
147    println!(
148        "Default reject all elements: {:?} -> {:?}",
149        numbers, filtered
150    );
151
152    // Scenario 3: Configurable filter
153    fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
154        if enable_filter {
155            BoxPredicate::new(|x: &i32| *x > 3)
156        } else {
157            BoxPredicate::always_true()
158        }
159    }
160
161    let numbers = vec![1, 2, 3, 4, 5];
162
163    let filter_enabled = configurable_filter(true);
164    let filtered: Vec<_> = numbers
165        .iter()
166        .copied()
167        .filter(filter_enabled.into_fn())
168        .collect();
169    println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
170
171    let filter_disabled = configurable_filter(false);
172    let filtered: Vec<_> = numbers
173        .iter()
174        .copied()
175        .filter(filter_disabled.into_fn())
176        .collect();
177    println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
178}Sourcepub fn name(&self) -> Option<&str>
 
pub fn name(&self) -> Option<&str>
Examples found in repository?
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
11fn main() {
12    println!("=== BoxPredicate always_true/always_false Demo ===\n");
13
14    // BoxPredicate::always_true
15    let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
16    println!("BoxPredicate::always_true():");
17    println!("  test(&42): {}", always_true.test(&42));
18    println!("  test(&-1): {}", always_true.test(&-1));
19    println!("  test(&0): {}", always_true.test(&0));
20    println!("  name: {:?}", always_true.name());
21
22    // BoxPredicate::always_false
23    let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
24    println!("\nBoxPredicate::always_false():");
25    println!("  test(&42): {}", always_false.test(&42));
26    println!("  test(&-1): {}", always_false.test(&-1));
27    println!("  test(&0): {}", always_false.test(&0));
28    println!("  name: {:?}", always_false.name());
29
30    println!("\n=== RcPredicate always_true/always_false Demo ===\n");
31
32    // RcPredicate::always_true
33    let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
34    println!("RcPredicate::always_true():");
35    println!(
36        "  test(&\"hello\"): {}",
37        rc_always_true.test(&"hello".to_string())
38    );
39    println!(
40        "  test(&\"world\"): {}",
41        rc_always_true.test(&"world".to_string())
42    );
43    println!("  name: {:?}", rc_always_true.name());
44
45    // RcPredicate::always_false
46    let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
47    println!("\nRcPredicate::always_false():");
48    println!(
49        "  test(&\"hello\"): {}",
50        rc_always_false.test(&"hello".to_string())
51    );
52    println!(
53        "  test(&\"world\"): {}",
54        rc_always_false.test(&"world".to_string())
55    );
56    println!("  name: {:?}", rc_always_false.name());
57
58    // Can be cloned and reused
59    let rc_clone = rc_always_true.clone();
60    println!("\nAfter cloning, still usable:");
61    println!(
62        "  Original: test(&\"test\"): {}",
63        rc_always_true.test(&"test".to_string())
64    );
65    println!(
66        "  Clone: test(&\"test\"): {}",
67        rc_clone.test(&"test".to_string())
68    );
69
70    println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
71
72    // ArcPredicate::always_true
73    let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
74    println!("ArcPredicate::always_true():");
75    println!("  test(&100): {}", arc_always_true.test(&100));
76    println!("  test(&-100): {}", arc_always_true.test(&-100));
77    println!("  name: {:?}", arc_always_true.name());
78
79    // ArcPredicate::always_false
80    let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
81    println!("\nArcPredicate::always_false():");
82    println!("  test(&100): {}", arc_always_false.test(&100));
83    println!("  test(&-100): {}", arc_always_false.test(&-100));
84    println!("  name: {:?}", arc_always_false.name());
85
86    println!("\n=== Combining with other predicates ===\n");
87
88    // Combining with always_true (AND)
89    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
90    let combined_and_true = is_positive.and(BoxPredicate::always_true());
91    println!("is_positive AND always_true:");
92    println!(
93        "  test(&5): {} (equivalent to is_positive)",
94        combined_and_true.test(&5)
95    );
96    println!(
97        "  test(&-3): {} (equivalent to is_positive)",
98        combined_and_true.test(&-3)
99    );
100
101    // Combining with always_false (AND)
102    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
103    let combined_and_false = is_positive.and(BoxPredicate::always_false());
104    println!("\nis_positive AND always_false:");
105    println!("  test(&5): {} (always false)", combined_and_false.test(&5));
106    println!(
107        "  test(&-3): {} (always false)",
108        combined_and_false.test(&-3)
109    );
110
111    // Combining with always_true (OR)
112    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
113    let combined_or_true = is_positive.or(BoxPredicate::always_true());
114    println!("\nis_positive OR always_true:");
115    println!("  test(&5): {} (always true)", combined_or_true.test(&5));
116    println!("  test(&-3): {} (always true)", combined_or_true.test(&-3));
117
118    // Combining with always_false (OR)
119    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
120    let combined_or_false = is_positive.or(BoxPredicate::always_false());
121    println!("\nis_positive OR always_false:");
122    println!(
123        "  test(&5): {} (equivalent to is_positive)",
124        combined_or_false.test(&5)
125    );
126    println!(
127        "  test(&-3): {} (equivalent to is_positive)",
128        combined_or_false.test(&-3)
129    );
130
131    println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
132
133    // Scenario 1: Default pass-all filter
134    let numbers = vec![1, 2, 3, 4, 5];
135    let pass_all = BoxPredicate::<i32>::always_true();
136    let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
137    println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
138
139    // Scenario 2: Default reject-all filter
140    let numbers = vec![1, 2, 3, 4, 5];
141    let reject_all = BoxPredicate::<i32>::always_false();
142    let filtered: Vec<_> = numbers
143        .iter()
144        .copied()
145        .filter(reject_all.into_fn())
146        .collect();
147    println!(
148        "Default reject all elements: {:?} -> {:?}",
149        numbers, filtered
150    );
151
152    // Scenario 3: Configurable filter
153    fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
154        if enable_filter {
155            BoxPredicate::new(|x: &i32| *x > 3)
156        } else {
157            BoxPredicate::always_true()
158        }
159    }
160
161    let numbers = vec![1, 2, 3, 4, 5];
162
163    let filter_enabled = configurable_filter(true);
164    let filtered: Vec<_> = numbers
165        .iter()
166        .copied()
167        .filter(filter_enabled.into_fn())
168        .collect();
169    println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
170
171    let filter_disabled = configurable_filter(false);
172    let filtered: Vec<_> = numbers
173        .iter()
174        .copied()
175        .filter(filter_disabled.into_fn())
176        .collect();
177    println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
178}Sourcepub fn set_name(&mut self, name: &str)
 
pub fn set_name(&mut self, name: &str)
Examples found in repository?
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}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.
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure: 
|x: &T| -> bool - A function pointer: 
fn(&T) -> bool - A 
BoxPredicate<T> - An 
RcPredicate<T> - Another 
ArcPredicate<T>(will be moved) - Any type implementing 
Predicate<T> + Send + Sync 
- A closure: 
 
§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 usableExamples found in repository?
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}Sourcepub fn or<P>(&self, other: P) -> ArcPredicate<T>
 
pub fn or<P>(&self, other: P) -> ArcPredicate<T>
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 implementsClone). 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 
- A closure: 
 
§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 usableSourcepub fn not(&self) -> ArcPredicate<T>
 
pub fn not(&self) -> ArcPredicate<T>
Returns a predicate that represents the logical negation of this predicate.
§Returns
A new ArcPredicate 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).
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Accepts closures, function pointers, or anyPredicate<T> + Send + Syncimplementation.
§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) = falseSourcepub 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.
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone).
§Returns
A new ArcPredicate 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).
§Parameters
other- The other predicate to combine with. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Accepts closures, function pointers, or anyPredicate<T> + Send + Syncimplementation.
§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) = falseTrait 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: 'static> Predicate<T> for ArcPredicate<T>
 
impl<T: 'static> 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>
 
fn into_box(self) -> BoxPredicate<T>
BoxPredicate. Read moreSource§fn into_rc(self) -> RcPredicate<T>
 
fn into_rc(self) -> RcPredicate<T>
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>
 
fn to_box(&self) -> BoxPredicate<T>
BoxPredicate. Read moreSource§fn to_rc(&self) -> RcPredicate<T>
 
fn to_rc(&self) -> RcPredicate<T>
RcPredicate. Read moreSource§fn to_arc(&self) -> ArcPredicate<T>
 
fn to_arc(&self) -> ArcPredicate<T>
ArcPredicate. Read more