prism3_function/predicate.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025.
4 * 3-Prism Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # Predicate Abstraction
10//!
11//! Provides a Rust implementation similar to Java's `Predicate` interface
12//! for condition testing and logical composition.
13//!
14//! ## Core Semantics
15//!
16//! A **Predicate** is fundamentally a pure judgment operation that tests
17//! whether a value satisfies a specific condition. It should be:
18//!
19//! - **Read-only**: Does not modify the tested value
20//! - **Side-effect free**: Does not change external state (from the user's
21//! perspective)
22//! - **Repeatable**: Same input should produce the same result
23//! - **Deterministic**: Judgment logic should be predictable
24//!
25//! ## Design Philosophy
26//!
27//! This module follows these principles:
28//!
29//! 1. **Single Trait**: Only one `Predicate<T>` trait with `&self`, keeping
30//! the API simple and semantically clear
31//! 2. **No PredicateMut**: All stateful scenarios use interior mutability
32//! (`RefCell`, `Cell`, `Mutex`) instead of `&mut self`
33//! 3. **No PredicateOnce**: Violates predicate semantics - judgments should
34//! be repeatable
35//! 4. **Three Implementations**: `BoxPredicate`, `RcPredicate`, and
36//! `ArcPredicate` cover all ownership scenarios
37//!
38//! ## Type Selection Guide
39//!
40//! | Scenario | Recommended Type | Reason |
41//! |----------|------------------|--------|
42//! | One-time use | `BoxPredicate` | Single ownership, no overhead |
43//! | Multi-threaded | `ArcPredicate` | Thread-safe, clonable |
44//! | Single-threaded reuse | `RcPredicate` | Better performance |
45//! | Stateful predicate | Any type + `RefCell`/`Cell`/`Mutex` | Interior mutability |
46//!
47//! ## Examples
48//!
49//! ### Basic Usage with Closures
50//!
51//! ```rust
52//! use prism3_function::predicate::Predicate;
53//!
54//! let is_positive = |x: &i32| *x > 0;
55//! assert!(is_positive.test(&5));
56//! assert!(!is_positive.test(&-3));
57//! ```
58//!
59//! ### BoxPredicate - Single Ownership
60//!
61//! ```rust
62//! use prism3_function::predicate::{Predicate, BoxPredicate};
63//!
64//! let pred = BoxPredicate::new(|x: &i32| *x > 0)
65//! .and(BoxPredicate::new(|x| x % 2 == 0));
66//! assert!(pred.test(&4));
67//! ```
68//!
69//! ### Closure Composition with Extension Methods
70//!
71//! Closures automatically gain `and`, `or`, `not` methods through the
72//! `FnPredicateOps` extension trait, returning `BoxPredicate`:
73//!
74//! ```rust
75//! use prism3_function::predicate::{Predicate, FnPredicateOps, BoxPredicate};
76//!
77//! // Compose closures directly - result is BoxPredicate
78//! let is_positive = |x: &i32| *x > 0;
79//! let is_even = |x: &i32| x % 2 == 0;
80//!
81//! let positive_and_even = is_positive.and(is_even);
82//! assert!(positive_and_even.test(&4));
83//! assert!(!positive_and_even.test(&3));
84//!
85//! // Can chain multiple operations
86//! let pred = (|x: &i32| *x > 0)
87//! .and(|x: &i32| x % 2 == 0)
88//! .and(BoxPredicate::new(|x: &i32| *x < 100));
89//! assert!(pred.test(&42));
90//!
91//! // Use `or` for disjunction
92//! let negative_or_large = (|x: &i32| *x < 0)
93//! .or(|x: &i32| *x > 100);
94//! assert!(negative_or_large.test(&-5));
95//! assert!(negative_or_large.test(&200));
96//!
97//! // Use `not` for negation
98//! let not_zero = (|x: &i32| *x == 0).not();
99//! assert!(not_zero.test(&5));
100//! assert!(!not_zero.test(&0));
101//! ```
102//!
103//! ### Complex Predicate Composition
104//!
105//! Build complex predicates by mixing closures and predicate types:
106//!
107//! ```rust
108//! use prism3_function::predicate::{Predicate, BoxPredicate, FnPredicateOps};
109//!
110//! // Start with a closure, compose with BoxPredicate
111//! let in_range = (|x: &i32| *x >= 0)
112//! .and(BoxPredicate::new(|x| *x <= 100));
113//!
114//! // Use in filtering
115//! let numbers = vec![-10, 5, 50, 150, 75];
116//! let filtered: Vec<_> = numbers.iter()
117//! .copied()
118//! .filter(in_range.into_fn())
119//! .collect();
120//! assert_eq!(filtered, vec![5, 50, 75]);
121//! ```
122//!
123//! ### RcPredicate - Single-threaded Reuse
124//!
125//! ```rust
126//! use prism3_function::predicate::{Predicate, RcPredicate};
127//!
128//! let pred = RcPredicate::new(|x: &i32| *x > 0);
129//! let combined1 = pred.and(RcPredicate::new(|x| x % 2 == 0));
130//! let combined2 = pred.or(RcPredicate::new(|x| *x > 100));
131//!
132//! // Original predicate is still usable
133//! assert!(pred.test(&5));
134//! ```
135//!
136//! ### ArcPredicate - Thread-safe Sharing
137//!
138//! ```rust
139//! use prism3_function::predicate::{Predicate, ArcPredicate};
140//! use std::thread;
141//!
142//! let pred = ArcPredicate::new(|x: &i32| *x > 0);
143//! let pred_clone = pred.clone();
144//!
145//! let handle = thread::spawn(move || {
146//! pred_clone.test(&10)
147//! });
148//!
149//! assert!(handle.join().unwrap());
150//! assert!(pred.test(&5)); // Original still usable
151//! ```
152//!
153//! ### Stateful Predicates with Interior Mutability
154//!
155//! ```rust
156//! use prism3_function::predicate::{Predicate, BoxPredicate};
157//! use std::cell::Cell;
158//!
159//! let count = Cell::new(0);
160//! let pred = BoxPredicate::new(move |x: &i32| {
161//! count.set(count.get() + 1);
162//! *x > 0
163//! });
164//!
165//! // No need for `mut` - interior mutability handles state
166//! assert!(pred.test(&5));
167//! assert!(!pred.test(&-3));
168//! ```
169//!
170//! ## Author
171//!
172//! Haixing Hu
173
174use std::fmt::{Debug, Display};
175use std::rc::Rc;
176use std::sync::Arc;
177
178/// Predicate name constant for always-true predicates
179const ALWAYS_TRUE_NAME: &str = "always_true";
180
181/// Predicate name constant for always-false predicates
182const ALWAYS_FALSE_NAME: &str = "always_false";
183
184/// A predicate trait for testing whether a value satisfies a condition.
185///
186/// This trait represents a **pure judgment operation** - it tests whether
187/// a given value meets certain criteria without modifying either the value
188/// or the predicate itself (from the user's perspective). This semantic
189/// clarity distinguishes predicates from consumers or transformers.
190///
191/// ## Design Rationale
192///
193/// This is a **minimal trait** that only defines:
194/// - The core `test` method using `&self` (immutable borrow)
195/// - Type conversion methods (`into_box`, `into_rc`, `into_arc`)
196/// - Closure conversion method (`into_fn`)
197///
198/// Logical composition methods (`and`, `or`, `not`) are intentionally
199/// **not** part of the trait. Instead, they are implemented on concrete
200/// types (`BoxPredicate`, `RcPredicate`, `ArcPredicate`), allowing each
201/// implementation to maintain its specific ownership characteristics:
202///
203/// - `BoxPredicate`: Methods consume `self` (single ownership)
204/// - `RcPredicate`: Methods borrow `&self` (shared ownership)
205/// - `ArcPredicate`: Methods borrow `&self` (thread-safe shared ownership)
206///
207/// ## Why `&self` Instead of `&mut self`?
208///
209/// Predicates use `&self` because:
210///
211/// 1. **Semantic Clarity**: A predicate is a judgment, not a mutation
212/// 2. **Flexibility**: Can be used in immutable contexts
213/// 3. **Simplicity**: No need for `mut` in user code
214/// 4. **Interior Mutability**: State (if needed) can be managed with
215/// `RefCell`, `Cell`, or `Mutex`
216///
217/// ## Automatic Implementation for Closures
218///
219/// Any closure matching `Fn(&T) -> bool` automatically implements this
220/// trait, providing seamless integration with Rust's closure system.
221///
222/// ## Examples
223///
224/// ### Basic Usage
225///
226/// ```rust
227/// use prism3_function::predicate::Predicate;
228///
229/// let is_positive = |x: &i32| *x > 0;
230/// assert!(is_positive.test(&5));
231/// assert!(!is_positive.test(&-3));
232/// ```
233///
234/// ### Type Conversion
235///
236/// ```rust
237/// use prism3_function::predicate::{Predicate, BoxPredicate};
238///
239/// let closure = |x: &i32| *x > 0;
240/// let boxed: BoxPredicate<i32> = closure.into_box();
241/// assert!(boxed.test(&5));
242/// ```
243///
244/// ### Stateful Predicate with Interior Mutability
245///
246/// ```rust
247/// use prism3_function::predicate::{Predicate, BoxPredicate};
248/// use std::cell::Cell;
249///
250/// let count = Cell::new(0);
251/// let counting_pred = BoxPredicate::new(move |x: &i32| {
252/// count.set(count.get() + 1);
253/// *x > 0
254/// });
255///
256/// // Note: No `mut` needed - interior mutability handles state
257/// assert!(counting_pred.test(&5));
258/// assert!(!counting_pred.test(&-3));
259/// ```
260///
261/// ## Author
262///
263/// Haixing Hu
264pub trait Predicate<T> {
265 /// Tests whether the given value satisfies this predicate.
266 ///
267 /// # Parameters
268 ///
269 /// * `value` - The value to test.
270 ///
271 /// # Returns
272 ///
273 /// `true` if the value satisfies this predicate, `false` otherwise.
274 fn test(&self, value: &T) -> bool;
275
276 /// Converts this predicate into a `BoxPredicate`.
277 ///
278 /// # Returns
279 ///
280 /// A `BoxPredicate` wrapping this predicate.
281 fn into_box(self) -> BoxPredicate<T>
282 where
283 Self: Sized + 'static,
284 T: 'static;
285
286 /// Converts this predicate into an `RcPredicate`.
287 ///
288 /// # Returns
289 ///
290 /// An `RcPredicate` wrapping this predicate.
291 fn into_rc(self) -> RcPredicate<T>
292 where
293 Self: Sized + 'static,
294 T: 'static;
295
296 /// Converts this predicate into an `ArcPredicate`.
297 ///
298 /// # Returns
299 ///
300 /// An `ArcPredicate` wrapping this predicate.
301 fn into_arc(self) -> ArcPredicate<T>
302 where
303 Self: Sized + Send + Sync + 'static,
304 T: Send + Sync + 'static;
305
306 /// Converts this predicate into a closure that can be used directly
307 /// with standard library methods.
308 ///
309 /// This method consumes the predicate and returns a closure with
310 /// signature `Fn(&T) -> bool`. Since `Fn` is a subtrait of `FnMut`,
311 /// the returned closure can be used in any context that requires
312 /// either `Fn(&T) -> bool` or `FnMut(&T) -> bool`, making it
313 /// compatible with methods like `Iterator::filter`,
314 /// `Iterator::filter_map`, `Vec::retain`, and similar standard
315 /// library APIs.
316 ///
317 /// # Returns
318 ///
319 /// A closure implementing `Fn(&T) -> bool` (also usable as
320 /// `FnMut(&T) -> bool`).
321 ///
322 /// # Examples
323 ///
324 /// ## Using with `Iterator::filter` (requires `FnMut`)
325 ///
326 /// ```rust
327 /// use prism3_function::predicate::{Predicate, BoxPredicate};
328 ///
329 /// let pred = BoxPredicate::new(|x: &i32| *x > 0);
330 ///
331 /// let numbers = vec![-2, -1, 0, 1, 2, 3];
332 /// let positives: Vec<_> = numbers.iter()
333 /// .copied()
334 /// .filter(pred.into_fn())
335 /// .collect();
336 /// assert_eq!(positives, vec![1, 2, 3]);
337 /// ```
338 ///
339 /// ## Using with `Vec::retain` (requires `FnMut`)
340 ///
341 /// ```rust
342 /// use prism3_function::predicate::{Predicate, BoxPredicate};
343 ///
344 /// let pred = BoxPredicate::new(|x: &i32| *x % 2 == 0);
345 /// let mut numbers = vec![1, 2, 3, 4, 5, 6];
346 /// numbers.retain(pred.into_fn());
347 /// assert_eq!(numbers, vec![2, 4, 6]);
348 /// ```
349 fn into_fn(self) -> impl Fn(&T) -> bool
350 where
351 Self: Sized + 'static,
352 T: 'static;
353}
354
355/// A Box-based predicate with single ownership.
356///
357/// This type is suitable for one-time use scenarios where the predicate does
358/// not need to be cloned or shared. Composition methods consume `self`,
359/// reflecting the single-ownership model.
360///
361/// # Examples
362///
363/// ```rust
364/// use prism3_function::predicate::{Predicate, BoxPredicate};
365///
366/// let pred = BoxPredicate::new(|x: &i32| *x > 0);
367/// assert!(pred.test(&5));
368///
369/// // Chaining consumes the predicate
370/// let combined = pred.and(BoxPredicate::new(|x| x % 2 == 0));
371/// assert!(combined.test(&4));
372/// ```
373///
374/// # Author
375///
376/// Haixing Hu
377pub struct BoxPredicate<T> {
378 function: Box<dyn Fn(&T) -> bool>,
379 name: Option<String>,
380}
381
382impl<T: 'static> BoxPredicate<T> {
383 /// Creates a new `BoxPredicate` from a closure.
384 ///
385 /// # Parameters
386 ///
387 /// * `f` - The closure to wrap.
388 ///
389 /// # Returns
390 ///
391 /// A new `BoxPredicate` instance.
392 pub fn new<F>(f: F) -> Self
393 where
394 F: Fn(&T) -> bool + 'static,
395 {
396 Self {
397 function: Box::new(f),
398 name: None,
399 }
400 }
401
402 /// Creates a named `BoxPredicate` from a closure.
403 ///
404 /// # Parameters
405 ///
406 /// * `name` - The name for this predicate.
407 /// * `f` - The closure to wrap.
408 ///
409 /// # Returns
410 ///
411 /// A new named `BoxPredicate` instance.
412 pub fn new_with_name<F>(name: &str, f: F) -> Self
413 where
414 F: Fn(&T) -> bool + 'static,
415 {
416 Self {
417 function: Box::new(f),
418 name: Some(name.to_string()),
419 }
420 }
421
422 /// Creates a predicate that always returns `true`.
423 ///
424 /// # Returns
425 ///
426 /// A new `BoxPredicate` that always returns `true`.
427 ///
428 /// # Examples
429 ///
430 /// ```rust
431 /// use prism3_function::predicate::{Predicate, BoxPredicate};
432 ///
433 /// let pred: BoxPredicate<i32> = BoxPredicate::always_true();
434 /// assert!(pred.test(&42));
435 /// assert!(pred.test(&-1));
436 /// assert!(pred.test(&0));
437 /// ```
438 pub fn always_true() -> Self {
439 Self {
440 function: Box::new(|_| true),
441 name: Some(ALWAYS_TRUE_NAME.to_string()),
442 }
443 }
444
445 /// Creates a predicate that always returns `false`.
446 ///
447 /// # Returns
448 ///
449 /// A new `BoxPredicate` that always returns `false`.
450 ///
451 /// # Examples
452 ///
453 /// ```rust
454 /// use prism3_function::predicate::{Predicate, BoxPredicate};
455 ///
456 /// let pred: BoxPredicate<i32> = BoxPredicate::always_false();
457 /// assert!(!pred.test(&42));
458 /// assert!(!pred.test(&-1));
459 /// assert!(!pred.test(&0));
460 /// ```
461 pub fn always_false() -> Self {
462 Self {
463 function: Box::new(|_| false),
464 name: Some(ALWAYS_FALSE_NAME.to_string()),
465 }
466 }
467
468 /// Returns the name of this predicate, if set.
469 ///
470 /// # Returns
471 ///
472 /// An `Option` containing the predicate's name.
473 pub fn name(&self) -> Option<&str> {
474 self.name.as_deref()
475 }
476
477 /// Sets the name of this predicate.
478 ///
479 /// # Parameters
480 ///
481 /// * `name` - The new name for this predicate.
482 pub fn set_name(&mut self, name: &str) {
483 self.name = Some(name.to_string());
484 }
485
486 /// Returns a predicate that represents the logical AND of this predicate
487 /// and another.
488 ///
489 /// This method consumes `self` due to single-ownership semantics.
490 ///
491 /// # Parameters
492 ///
493 /// * `other` - The other predicate to combine with. **Note: This parameter
494 /// is passed by value and will transfer ownership.** If you need to
495 /// preserve the original predicate, clone it first (if it implements
496 /// `Clone`). Can be:
497 /// - A closure: `|x: &T| -> bool`
498 /// - A function pointer: `fn(&T) -> bool`
499 /// - Another `BoxPredicate<T>`
500 /// - An `RcPredicate<T>`
501 /// - An `ArcPredicate<T>`
502 /// - Any type implementing `Predicate<T>`
503 ///
504 /// # Returns
505 ///
506 /// A new `BoxPredicate` representing the logical AND.
507 ///
508 /// # Examples
509 ///
510 /// ## Combining with closures
511 ///
512 /// ```rust
513 /// use prism3_function::predicate::{Predicate, BoxPredicate};
514 ///
515 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
516 /// let is_even = |x: &i32| x % 2 == 0;
517 ///
518 /// // Note: is_positive is moved here, so it's no longer usable
519 /// let combined = is_positive.and(is_even);
520 /// assert!(combined.test(&4)); // positive and even
521 /// assert!(!combined.test(&3)); // positive but odd
522 /// assert!(!combined.test(&-2)); // even but negative
523 /// // is_positive.test(&5); // This would not compile - is_positive was moved
524 /// ```
525 ///
526 /// ## Combining with function pointers
527 ///
528 /// ```rust
529 /// use prism3_function::predicate::{Predicate, BoxPredicate};
530 ///
531 /// fn is_even(x: &i32) -> bool { x % 2 == 0 }
532 ///
533 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
534 /// let combined = is_positive.and(is_even);
535 ///
536 /// assert!(combined.test(&4));
537 /// assert!(!combined.test(&3));
538 /// ```
539 ///
540 /// ## Combining with other BoxPredicate
541 ///
542 /// ```rust
543 /// use prism3_function::predicate::{Predicate, BoxPredicate};
544 ///
545 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
546 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
547 ///
548 /// let combined = is_positive.and(is_even);
549 /// assert!(combined.test(&4));
550 /// assert!(!combined.test(&3));
551 /// ```
552 ///
553 /// ## Chained composition
554 ///
555 /// ```rust
556 /// use prism3_function::predicate::{Predicate, BoxPredicate};
557 ///
558 /// let pred = BoxPredicate::new(|x: &i32| *x > 0)
559 /// .and(|x: &i32| x % 2 == 0)
560 /// .and(|x: &i32| *x < 100);
561 ///
562 /// assert!(pred.test(&42)); // positive, even, less than 100
563 /// assert!(!pred.test(&101)); // does not satisfy less than 100
564 /// ```
565 ///
566 /// ## Preserving original predicates with clone
567 ///
568 /// ```rust
569 /// use prism3_function::predicate::{Predicate, BoxPredicate};
570 ///
571 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
572 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
573 ///
574 /// // Clone the predicates to preserve them for later use
575 /// let combined = is_positive.clone().and(is_even.clone());
576 /// assert!(combined.test(&4));
577 ///
578 /// // Original predicates are still usable
579 /// assert!(is_positive.test(&5));
580 /// assert!(is_even.test(&6));
581 /// ```
582 pub fn and<P>(self, other: P) -> BoxPredicate<T>
583 where
584 P: Predicate<T> + 'static,
585 {
586 BoxPredicate {
587 function: Box::new(move |value: &T| (self.function)(value) && other.test(value)),
588 name: None,
589 }
590 }
591
592 /// Returns a predicate that represents the logical OR of this predicate
593 /// and another.
594 ///
595 /// This method consumes `self` due to single-ownership semantics.
596 ///
597 /// # Parameters
598 ///
599 /// * `other` - The other predicate to combine with. **Note: This parameter
600 /// is passed by value and will transfer ownership.** If you need to
601 /// preserve the original predicate, clone it first (if it implements
602 /// `Clone`). Can be:
603 /// - A closure: `|x: &T| -> bool`
604 /// - A function pointer: `fn(&T) -> bool`
605 /// - Another `BoxPredicate<T>`
606 /// - An `RcPredicate<T>`
607 /// - An `ArcPredicate<T>`
608 /// - Any type implementing `Predicate<T>`
609 ///
610 /// # Returns
611 ///
612 /// A new `BoxPredicate` representing the logical OR.
613 ///
614 /// # Examples
615 ///
616 /// ## Combining with closures
617 ///
618 /// ```rust
619 /// use prism3_function::predicate::{Predicate, BoxPredicate};
620 ///
621 /// let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
622 /// let is_large = |x: &i32| *x > 100;
623 ///
624 /// // Note: is_negative is moved here, so it's no longer usable
625 /// let combined = is_negative.or(is_large);
626 /// assert!(combined.test(&-5)); // negative
627 /// assert!(combined.test(&150)); // greater than 100
628 /// assert!(!combined.test(&50)); // neither negative nor greater than 100
629 /// // is_negative.test(&-10); // This would not compile - is_negative was moved
630 /// ```
631 ///
632 /// ## Combining with function pointers
633 ///
634 /// ```rust
635 /// use prism3_function::predicate::{Predicate, BoxPredicate};
636 ///
637 /// fn is_large(x: &i32) -> bool { *x > 100 }
638 ///
639 /// let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
640 /// let combined = is_negative.or(is_large);
641 ///
642 /// assert!(combined.test(&-5));
643 /// assert!(combined.test(&150));
644 /// ```
645 ///
646 /// ## Combining with other BoxPredicate
647 ///
648 /// ```rust
649 /// use prism3_function::predicate::{Predicate, BoxPredicate};
650 ///
651 /// let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
652 /// let is_large = BoxPredicate::new(|x: &i32| *x > 100);
653 ///
654 /// let combined = is_negative.or(is_large);
655 /// assert!(combined.test(&-5));
656 /// assert!(combined.test(&150));
657 /// ```
658 ///
659 /// ## Preserving original predicates with clone
660 ///
661 /// ```rust
662 /// use prism3_function::predicate::{Predicate, BoxPredicate};
663 ///
664 /// let is_negative = BoxPredicate::new(|x: &i32| *x < 0);
665 /// let is_large = BoxPredicate::new(|x: &i32| *x > 100);
666 ///
667 /// // Clone the predicates to preserve them for later use
668 /// let combined = is_negative.clone().or(is_large.clone());
669 /// assert!(combined.test(&-5));
670 /// assert!(combined.test(&150));
671 ///
672 /// // Original predicates are still usable
673 /// assert!(is_negative.test(&-10));
674 /// assert!(is_large.test(&200));
675 /// ```
676 pub fn or<P>(self, other: P) -> BoxPredicate<T>
677 where
678 P: Predicate<T> + 'static,
679 {
680 BoxPredicate {
681 function: Box::new(move |value: &T| (self.function)(value) || other.test(value)),
682 name: None,
683 }
684 }
685
686 /// Returns a predicate that represents the logical negation of this
687 /// predicate.
688 ///
689 /// This method consumes `self` due to single-ownership semantics.
690 ///
691 /// # Returns
692 ///
693 /// A new `BoxPredicate` representing the logical negation.
694 #[allow(clippy::should_implement_trait)]
695 pub fn not(self) -> BoxPredicate<T> {
696 BoxPredicate {
697 function: Box::new(move |value: &T| !(self.function)(value)),
698 name: None,
699 }
700 }
701
702 /// Returns a predicate that represents the logical NAND (NOT AND) of this
703 /// predicate and another.
704 ///
705 /// NAND returns `true` unless both predicates are `true`.
706 /// Equivalent to `!(self AND other)`.
707 ///
708 /// This method consumes `self` due to single-ownership semantics.
709 ///
710 /// # Parameters
711 ///
712 /// * `other` - The other predicate to combine with. **Note: This parameter
713 /// is passed by value and will transfer ownership.** If you need to
714 /// preserve the original predicate, clone it first (if it implements
715 /// `Clone`). Can be:
716 /// - A closure: `|x: &T| -> bool`
717 /// - A function pointer: `fn(&T) -> bool`
718 /// - Another `BoxPredicate<T>`
719 /// - An `RcPredicate<T>`
720 /// - An `ArcPredicate<T>`
721 /// - Any type implementing `Predicate<T>`
722 ///
723 /// # Returns
724 ///
725 /// A new `BoxPredicate` representing the logical NAND.
726 ///
727 /// # Examples
728 ///
729 /// ## Combining with closures
730 ///
731 /// ```rust
732 /// use prism3_function::predicate::{Predicate, BoxPredicate};
733 ///
734 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
735 /// let is_even = |x: &i32| x % 2 == 0;
736 ///
737 /// // Note: is_positive is moved here, so it's no longer usable
738 /// let nand = is_positive.nand(is_even);
739 /// assert!(nand.test(&3)); // positive but odd: !(true && false) = true
740 /// assert!(nand.test(&-2)); // even but negative: !(false && true) = true
741 /// assert!(!nand.test(&4)); // positive and even: !(true && true) = false
742 /// // is_positive.test(&5); // This would not compile - is_positive was moved
743 /// ```
744 ///
745 /// ## Combining with function pointers
746 ///
747 /// ```rust
748 /// use prism3_function::predicate::{Predicate, BoxPredicate};
749 ///
750 /// fn is_even(x: &i32) -> bool { x % 2 == 0 }
751 ///
752 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
753 /// let nand = is_positive.nand(is_even);
754 ///
755 /// assert!(nand.test(&3));
756 /// assert!(!nand.test(&4));
757 /// ```
758 ///
759 /// ## Combining with other BoxPredicate
760 ///
761 /// ```rust
762 /// use prism3_function::predicate::{Predicate, BoxPredicate};
763 ///
764 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
765 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
766 ///
767 /// let nand = is_positive.nand(is_even);
768 /// assert!(nand.test(&3)); // returns true when only one condition is met
769 /// assert!(!nand.test(&4)); // returns false when both conditions are met
770 /// ```
771 ///
772 /// ## Preserving original predicates with clone
773 ///
774 /// ```rust
775 /// use prism3_function::predicate::{Predicate, BoxPredicate};
776 ///
777 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
778 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
779 ///
780 /// // Clone the predicates to preserve them for later use
781 /// let nand = is_positive.clone().nand(is_even.clone());
782 /// assert!(nand.test(&3)); // returns true when only one condition is met
783 /// assert!(!nand.test(&4)); // returns false when both conditions are met
784 ///
785 /// // Original predicates are still usable
786 /// assert!(is_positive.test(&5));
787 /// assert!(is_even.test(&6));
788 /// ```
789 pub fn nand<P>(self, other: P) -> BoxPredicate<T>
790 where
791 P: Predicate<T> + 'static,
792 {
793 BoxPredicate {
794 function: Box::new(move |value: &T| !((self.function)(value) && other.test(value))),
795 name: None,
796 }
797 }
798
799 /// Returns a predicate that represents the logical XOR (exclusive OR) of
800 /// this predicate and another.
801 ///
802 /// XOR returns `true` if exactly one of the predicates is `true`.
803 ///
804 /// This method consumes `self` due to single-ownership semantics.
805 ///
806 /// # Parameters
807 ///
808 /// * `other` - The other predicate to combine with. **Note: This parameter
809 /// is passed by value and will transfer ownership.** If you need to
810 /// preserve the original predicate, clone it first (if it implements
811 /// `Clone`). Can be:
812 /// - A closure: `|x: &T| -> bool`
813 /// - A function pointer: `fn(&T) -> bool`
814 /// - Another `BoxPredicate<T>`
815 /// - An `RcPredicate<T>`
816 /// - An `ArcPredicate<T>`
817 /// - Any type implementing `Predicate<T>`
818 ///
819 /// # Returns
820 ///
821 /// A new `BoxPredicate` representing the logical XOR.
822 ///
823 /// # Examples
824 ///
825 /// ## Combining with closures
826 ///
827 /// ```rust
828 /// use prism3_function::predicate::{Predicate, BoxPredicate};
829 ///
830 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
831 /// let is_even = |x: &i32| x % 2 == 0;
832 ///
833 /// // Note: is_positive is moved here, so it's no longer usable
834 /// let xor = is_positive.xor(is_even);
835 /// assert!(xor.test(&3)); // positive but odd: true ^ false = true
836 /// assert!(xor.test(&-2)); // even but negative: false ^ true = true
837 /// assert!(!xor.test(&4)); // positive and even: true ^ true = false
838 /// assert!(!xor.test(&-1)); // negative and odd: false ^ false = false
839 /// // is_positive.test(&5); // This would not compile - is_positive was moved
840 /// ```
841 ///
842 /// ## Combining with function pointers
843 ///
844 /// ```rust
845 /// use prism3_function::predicate::{Predicate, BoxPredicate};
846 ///
847 /// fn is_even(x: &i32) -> bool { x % 2 == 0 }
848 ///
849 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
850 /// let xor = is_positive.xor(is_even);
851 ///
852 /// assert!(xor.test(&3));
853 /// assert!(!xor.test(&4));
854 /// ```
855 ///
856 /// ## Combining with other BoxPredicate
857 ///
858 /// ```rust
859 /// use prism3_function::predicate::{Predicate, BoxPredicate};
860 ///
861 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
862 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
863 ///
864 /// let xor = is_positive.xor(is_even);
865 /// assert!(xor.test(&3)); // returns true when only one condition is met
866 /// assert!(!xor.test(&4)); // returns false when both conditions are met
867 /// assert!(!xor.test(&-1)); // returns false when neither condition is met
868 /// ```
869 ///
870 /// ## Preserving original predicates with clone
871 ///
872 /// ```rust
873 /// use prism3_function::predicate::{Predicate, BoxPredicate};
874 ///
875 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
876 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
877 ///
878 /// // Clone the predicates to preserve them for later use
879 /// let xor = is_positive.clone().xor(is_even.clone());
880 /// assert!(xor.test(&3)); // returns true when only one condition is met
881 /// assert!(!xor.test(&4)); // returns false when both conditions are met
882 /// assert!(!xor.test(&-1)); // returns false when neither condition is met
883 ///
884 /// // Original predicates are still usable
885 /// assert!(is_positive.test(&5));
886 /// assert!(is_even.test(&6));
887 /// ```
888 pub fn xor<P>(self, other: P) -> BoxPredicate<T>
889 where
890 P: Predicate<T> + 'static,
891 {
892 BoxPredicate {
893 function: Box::new(move |value: &T| (self.function)(value) ^ other.test(value)),
894 name: None,
895 }
896 }
897
898 /// Returns a predicate that represents the logical NOR (NOT OR) of this
899 /// predicate and another.
900 ///
901 /// NOR returns `true` only when both predicates are `false`. Equivalent
902 /// to `!(self OR other)`.
903 ///
904 /// This method consumes `self` due to single-ownership semantics.
905 ///
906 /// # Parameters
907 ///
908 /// * `other` - The other predicate to combine with. **Note: This parameter
909 /// is passed by value and will transfer ownership.** If you need to
910 /// preserve the original predicate, clone it first (if it implements
911 /// `Clone`). Can be:
912 /// - A closure: `|x: &T| -> bool`
913 /// - A function pointer: `fn(&T) -> bool`
914 /// - Another `BoxPredicate<T>`
915 /// - An `RcPredicate<T>`
916 /// - An `ArcPredicate<T>`
917 /// - Any type implementing `Predicate<T>`
918 ///
919 /// # Returns
920 ///
921 /// A new `BoxPredicate` representing the logical NOR.
922 ///
923 /// # Examples
924 ///
925 /// ## Combining with closures
926 ///
927 /// ```rust
928 /// use prism3_function::predicate::{Predicate, BoxPredicate};
929 ///
930 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
931 /// let is_even = |x: &i32| x % 2 == 0;
932 ///
933 /// // Note: is_positive is moved here, so it's no longer usable
934 /// let nor = is_positive.nor(is_even);
935 /// assert!(nor.test(&-3)); // Neither positive nor even:
936 /// // !(false || false) = true
937 /// assert!(!nor.test(&4)); // Both positive and even:
938 /// // !(true || true) = false
939 /// assert!(!nor.test(&3)); // Positive but not even:
940 /// // !(true || false) = false
941 /// assert!(!nor.test(&-2)); // Even but not positive:
942 /// // !(false || true) = false
943 /// // is_positive.test(&5); // This would not compile - is_positive was moved
944 /// ```
945 ///
946 /// ## Combining with function pointers
947 ///
948 /// ```rust
949 /// use prism3_function::predicate::{Predicate, BoxPredicate};
950 ///
951 /// fn is_even(x: &i32) -> bool { x % 2 == 0 }
952 ///
953 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
954 /// let nor = is_positive.nor(is_even);
955 ///
956 /// assert!(nor.test(&-3));
957 /// assert!(!nor.test(&4));
958 /// ```
959 ///
960 /// ## Combining with other BoxPredicate
961 ///
962 /// ```rust
963 /// use prism3_function::predicate::{Predicate, BoxPredicate};
964 ///
965 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
966 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
967 ///
968 /// let nor = is_positive.nor(is_even);
969 /// assert!(nor.test(&-3)); // Returns true only when both are false
970 /// assert!(!nor.test(&4)); // Returns false when at least one is true
971 /// ```
972 ///
973 /// ## Preserving original predicates with clone
974 ///
975 /// ```rust
976 /// use prism3_function::predicate::{Predicate, BoxPredicate};
977 ///
978 /// let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
979 /// let is_even = BoxPredicate::new(|x: &i32| x % 2 == 0);
980 ///
981 /// // Clone the predicates to preserve them for later use
982 /// let nor = is_positive.clone().nor(is_even.clone());
983 /// assert!(nor.test(&-3)); // Returns true only when both are false
984 /// assert!(!nor.test(&4)); // Returns false when at least one is true
985 ///
986 /// // Original predicates are still usable
987 /// assert!(is_positive.test(&5));
988 /// assert!(is_even.test(&6));
989 /// ```
990 pub fn nor<P>(self, other: P) -> BoxPredicate<T>
991 where
992 P: Predicate<T> + 'static,
993 {
994 BoxPredicate {
995 function: Box::new(move |value: &T| !((self.function)(value) || other.test(value))),
996 name: None,
997 }
998 }
999}
1000
1001impl<T: 'static> Predicate<T> for BoxPredicate<T> {
1002 fn test(&self, value: &T) -> bool {
1003 (self.function)(value)
1004 }
1005
1006 fn into_box(self) -> BoxPredicate<T> {
1007 self
1008 }
1009
1010 fn into_rc(self) -> RcPredicate<T> {
1011 RcPredicate {
1012 function: Rc::from(self.function),
1013 name: self.name,
1014 }
1015 }
1016
1017 fn into_arc(self) -> ArcPredicate<T>
1018 where
1019 T: Send + Sync,
1020 {
1021 // This is a best-effort conversion. If the underlying function
1022 // is not Send + Sync, this will fail at compile time.
1023 // Users should use ArcPredicate::new directly if they need
1024 // guaranteed Send + Sync.
1025 panic!("BoxPredicate cannot be converted to ArcPredicate - use ArcPredicate::new directly")
1026 }
1027
1028 fn into_fn(self) -> impl Fn(&T) -> bool {
1029 move |value: &T| (self.function)(value)
1030 }
1031}
1032
1033impl<T> Display for BoxPredicate<T> {
1034 /// Implements Display trait for BoxPredicate
1035 ///
1036 /// Shows the predicate name if available, or "unnamed" as default.
1037 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1038 write!(
1039 f,
1040 "BoxPredicate({})",
1041 self.name.as_deref().unwrap_or("unnamed")
1042 )
1043 }
1044}
1045
1046impl<T> Debug for BoxPredicate<T> {
1047 /// Implements Debug trait for BoxPredicate
1048 ///
1049 /// Shows the predicate name in debug struct format.
1050 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1051 f.debug_struct("BoxPredicate")
1052 .field("name", &self.name)
1053 .finish()
1054 }
1055}
1056
1057/// An Rc-based predicate with single-threaded shared ownership.
1058///
1059/// This type is suitable for scenarios where the predicate needs to be
1060/// reused in a single-threaded context. Composition methods borrow `&self`,
1061/// allowing the original predicate to remain usable after composition.
1062///
1063/// # Examples
1064///
1065/// ```rust
1066/// use prism3_function::predicate::{Predicate, RcPredicate};
1067///
1068/// let pred = RcPredicate::new(|x: &i32| *x > 0);
1069/// assert!(pred.test(&5));
1070///
1071/// // Original predicate remains usable after composition
1072/// let combined = pred.and(RcPredicate::new(|x| x % 2 == 0));
1073/// assert!(pred.test(&5)); // Still works
1074/// ```
1075///
1076/// # Author
1077///
1078/// Haixing Hu
1079pub struct RcPredicate<T> {
1080 function: Rc<dyn Fn(&T) -> bool>,
1081 name: Option<String>,
1082}
1083
1084impl<T: 'static> RcPredicate<T> {
1085 /// Creates a new `RcPredicate` from a closure.
1086 ///
1087 /// # Parameters
1088 ///
1089 /// * `f` - The closure to wrap.
1090 ///
1091 /// # Returns
1092 ///
1093 /// A new `RcPredicate` instance.
1094 pub fn new<F>(f: F) -> Self
1095 where
1096 F: Fn(&T) -> bool + 'static,
1097 {
1098 Self {
1099 function: Rc::new(f),
1100 name: None,
1101 }
1102 }
1103
1104 /// Creates a named `RcPredicate` from a closure.
1105 ///
1106 /// # Parameters
1107 ///
1108 /// * `name` - The name for this predicate.
1109 /// * `f` - The closure to wrap.
1110 ///
1111 /// # Returns
1112 ///
1113 /// A new named `RcPredicate` instance.
1114 pub fn new_with_name<F>(name: &str, f: F) -> Self
1115 where
1116 F: Fn(&T) -> bool + 'static,
1117 {
1118 Self {
1119 function: Rc::new(f),
1120 name: Some(name.to_string()),
1121 }
1122 }
1123
1124 /// Creates a predicate that always returns `true`.
1125 ///
1126 /// # Returns
1127 ///
1128 /// A new `RcPredicate` that always returns `true`.
1129 ///
1130 /// # Examples
1131 ///
1132 /// ```rust
1133 /// use prism3_function::predicate::{Predicate, RcPredicate};
1134 ///
1135 /// let pred: RcPredicate<i32> = RcPredicate::always_true();
1136 /// assert!(pred.test(&42));
1137 /// assert!(pred.test(&-1));
1138 /// assert!(pred.test(&0));
1139 /// ```
1140 pub fn always_true() -> Self {
1141 Self {
1142 function: Rc::new(|_| true),
1143 name: Some(ALWAYS_TRUE_NAME.to_string()),
1144 }
1145 }
1146
1147 /// Creates a predicate that always returns `false`.
1148 ///
1149 /// # Returns
1150 ///
1151 /// A new `RcPredicate` that always returns `false`.
1152 ///
1153 /// # Examples
1154 ///
1155 /// ```rust
1156 /// use prism3_function::predicate::{Predicate, RcPredicate};
1157 ///
1158 /// let pred: RcPredicate<i32> = RcPredicate::always_false();
1159 /// assert!(!pred.test(&42));
1160 /// assert!(!pred.test(&-1));
1161 /// assert!(!pred.test(&0));
1162 /// ```
1163 pub fn always_false() -> Self {
1164 Self {
1165 function: Rc::new(|_| false),
1166 name: Some(ALWAYS_FALSE_NAME.to_string()),
1167 }
1168 }
1169
1170 /// Returns the name of this predicate, if set.
1171 ///
1172 /// # Returns
1173 ///
1174 /// An `Option` containing the predicate's name.
1175 pub fn name(&self) -> Option<&str> {
1176 self.name.as_deref()
1177 }
1178
1179 /// Sets the name of this predicate.
1180 ///
1181 /// # Parameters
1182 ///
1183 /// * `name` - The new name for this predicate.
1184 pub fn set_name(&mut self, name: &str) {
1185 self.name = Some(name.to_string());
1186 }
1187
1188 /// Returns a predicate that represents the logical AND of this predicate
1189 /// and another.
1190 ///
1191 /// # Parameters
1192 ///
1193 /// * `other` - The other predicate to combine with. **Note: This parameter
1194 /// is passed by value and will transfer ownership.** If you need to
1195 /// preserve the original predicate, clone it first (if it implements
1196 /// `Clone`). Can be:
1197 /// - A closure: `|x: &T| -> bool`
1198 /// - A function pointer: `fn(&T) -> bool`
1199 /// - A `BoxPredicate<T>`
1200 /// - Another `RcPredicate<T>` (will be moved)
1201 /// - An `ArcPredicate<T>`
1202 /// - Any type implementing `Predicate<T>`
1203 ///
1204 /// # Returns
1205 ///
1206 /// A new `RcPredicate` representing the logical AND.
1207 ///
1208 /// # Examples
1209 ///
1210 /// ## Combining with closures (original predicate remains usable)
1211 ///
1212 /// ```rust
1213 /// use prism3_function::predicate::{Predicate, RcPredicate};
1214 ///
1215 /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
1216 /// let is_even = |x: &i32| x % 2 == 0;
1217 ///
1218 /// // Note: is_positive is borrowed (&self), so it remains usable
1219 /// let combined = is_positive.and(is_even);
1220 /// assert!(combined.test(&4));
1221 /// assert!(!combined.test(&3));
1222 ///
1223 /// // original predicate remains usable because RcPredicate uses &self
1224 /// assert!(is_positive.test(&5));
1225 /// ```
1226 ///
1227 /// ## Combining with other RcPredicate (requires clone)
1228 ///
1229 /// ```rust
1230 /// use prism3_function::predicate::{Predicate, RcPredicate};
1231 ///
1232 /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
1233 /// let is_even = RcPredicate::new(|x: &i32| x % 2 == 0);
1234 ///
1235 /// // Note: is_even parameter is passed by value and will be moved
1236 /// // If you need to continue using is_even, you should clone it
1237 /// let combined = is_positive.and(is_even.clone());
1238 /// assert!(combined.test(&4));
1239 ///
1240 /// // both original predicates remain usable
1241 /// assert!(is_positive.test(&5));
1242 /// assert!(is_even.test(&6));
1243 /// ```
1244 ///
1245 /// ## Reusing the same predicate multiple times
1246 ///
1247 /// ```rust
1248 /// use prism3_function::predicate::{Predicate, RcPredicate};
1249 ///
1250 /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
1251 ///
1252 /// // Note: is_positive is borrowed (&self), so it can be reused
1253 /// let positive_and_even = is_positive.and(|x: &i32| x % 2 == 0);
1254 /// let positive_and_small = is_positive.and(|x: &i32| *x < 100);
1255 ///
1256 /// // is_positive can be combined multiple times because RcPredicate uses &self
1257 /// assert!(positive_and_even.test(&4));
1258 /// assert!(positive_and_small.test(&5));
1259 /// assert!(is_positive.test(&10));
1260 /// ```
1261 pub fn and<P>(&self, other: P) -> RcPredicate<T>
1262 where
1263 P: Predicate<T> + 'static,
1264 {
1265 let self_fn = Rc::clone(&self.function);
1266 RcPredicate {
1267 function: Rc::new(move |value: &T| self_fn(value) && other.test(value)),
1268 name: None,
1269 }
1270 }
1271
1272 /// Returns a predicate that represents the logical OR of this predicate
1273 /// and another.
1274 ///
1275 /// # Parameters
1276 ///
1277 /// * `other` - The other predicate to combine with. **Note: This parameter
1278 /// is passed by value and will transfer ownership.** If you need to
1279 /// preserve the original predicate, clone it first (if it implements
1280 /// `Clone`). Can be:
1281 /// - A closure: `|x: &T| -> bool`
1282 /// - A function pointer: `fn(&T) -> bool`
1283 /// - A `BoxPredicate<T>`
1284 /// - Another `RcPredicate<T>` (will be moved)
1285 /// - An `ArcPredicate<T>`
1286 /// - Any type implementing `Predicate<T>`
1287 ///
1288 /// # Returns
1289 ///
1290 /// A new `RcPredicate` representing the logical OR.
1291 ///
1292 /// # Examples
1293 ///
1294 /// ```rust
1295 /// use prism3_function::predicate::{Predicate, RcPredicate};
1296 ///
1297 /// let is_negative = RcPredicate::new(|x: &i32| *x < 0);
1298 /// let is_large = |x: &i32| *x > 100;
1299 ///
1300 /// let combined = is_negative.or(is_large);
1301 /// assert!(combined.test(&-5));
1302 /// assert!(combined.test(&150));
1303 /// assert!(!combined.test(&50));
1304 ///
1305 /// // original predicate remains usable
1306 /// assert!(is_negative.test(&-10));
1307 /// ```
1308 pub fn or<P>(&self, other: P) -> RcPredicate<T>
1309 where
1310 P: Predicate<T> + 'static,
1311 {
1312 let self_fn = Rc::clone(&self.function);
1313 RcPredicate {
1314 function: Rc::new(move |value: &T| self_fn(value) || other.test(value)),
1315 name: None,
1316 }
1317 }
1318
1319 /// Returns a predicate that represents the logical negation of this
1320 /// predicate.
1321 ///
1322 /// # Returns
1323 ///
1324 /// A new `RcPredicate` representing the logical negation.
1325 #[allow(clippy::should_implement_trait)]
1326 pub fn not(&self) -> RcPredicate<T> {
1327 let self_fn = Rc::clone(&self.function);
1328 RcPredicate {
1329 function: Rc::new(move |value: &T| !self_fn(value)),
1330 name: None,
1331 }
1332 }
1333
1334 /// Returns a predicate that represents the logical NAND (NOT AND) of this
1335 /// predicate and another.
1336 ///
1337 /// NAND returns `true` unless both predicates are `true`.
1338 /// Equivalent to `!(self AND other)`.
1339 ///
1340 /// # Parameters
1341 ///
1342 /// * `other` - The other predicate to combine with. **Note: This parameter
1343 /// is passed by value and will transfer ownership.** If you need to
1344 /// preserve the original predicate, clone it first (if it implements
1345 /// `Clone`). Can be:
1346 /// - A closure: `|x: &T| -> bool`
1347 /// - A function pointer: `fn(&T) -> bool`
1348 /// - A `BoxPredicate<T>`
1349 /// - Another `RcPredicate<T>` (will be moved)
1350 /// - An `ArcPredicate<T>`
1351 /// - Any type implementing `Predicate<T>`
1352 ///
1353 /// # Returns
1354 ///
1355 /// A new `RcPredicate` representing the logical NAND.
1356 ///
1357 /// # Examples
1358 ///
1359 /// ```rust
1360 /// use prism3_function::predicate::{Predicate, RcPredicate};
1361 ///
1362 /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
1363 /// let is_even = |x: &i32| x % 2 == 0;
1364 ///
1365 /// let nand = is_positive.nand(is_even);
1366 /// assert!(nand.test(&3)); // !(true && false) = true
1367 /// assert!(!nand.test(&4)); // !(true && true) = false
1368 ///
1369 /// // original predicate remains usable
1370 /// assert!(is_positive.test(&5));
1371 /// ```
1372 pub fn nand<P>(&self, other: P) -> RcPredicate<T>
1373 where
1374 P: Predicate<T> + 'static,
1375 {
1376 let self_fn = Rc::clone(&self.function);
1377 RcPredicate {
1378 function: Rc::new(move |value: &T| !(self_fn(value) && other.test(value))),
1379 name: None,
1380 }
1381 }
1382
1383 /// Returns a predicate that represents the logical XOR (exclusive OR) of
1384 /// this predicate and another.
1385 ///
1386 /// XOR returns `true` if exactly one of the predicates is `true`.
1387 ///
1388 /// # Parameters
1389 ///
1390 /// * `other` - The other predicate to combine with. **Note: This parameter
1391 /// is passed by value and will transfer ownership.** If you need to
1392 /// preserve the original predicate, clone it first (if it implements
1393 /// `Clone`). Can be:
1394 /// - A closure: `|x: &T| -> bool`
1395 /// - A function pointer: `fn(&T) -> bool`
1396 /// - A `BoxPredicate<T>`
1397 /// - Another `RcPredicate<T>` (will be moved)
1398 /// - An `ArcPredicate<T>`
1399 /// - Any type implementing `Predicate<T>`
1400 ///
1401 /// # Returns
1402 ///
1403 /// A new `RcPredicate` representing the logical XOR.
1404 ///
1405 /// # Examples
1406 ///
1407 /// ```rust
1408 /// use prism3_function::predicate::{Predicate, RcPredicate};
1409 ///
1410 /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
1411 /// let is_even = |x: &i32| x % 2 == 0;
1412 ///
1413 /// let xor = is_positive.xor(is_even);
1414 /// assert!(xor.test(&3)); // true ^ false = true
1415 /// assert!(!xor.test(&4)); // true ^ true = false
1416 /// assert!(!xor.test(&-1)); // false ^ false = false
1417 ///
1418 /// // original predicate remains usable
1419 /// assert!(is_positive.test(&5));
1420 /// ```
1421 pub fn xor<P>(&self, other: P) -> RcPredicate<T>
1422 where
1423 P: Predicate<T> + 'static,
1424 {
1425 let self_fn = Rc::clone(&self.function);
1426 RcPredicate {
1427 function: Rc::new(move |value: &T| self_fn(value) ^ other.test(value)),
1428 name: None,
1429 }
1430 }
1431
1432 /// Returns a predicate that represents the logical NOR (NOT OR) of this
1433 /// predicate and another.
1434 ///
1435 /// NOR returns `true` only when both predicates are `false`. Equivalent
1436 /// to `!(self OR other)`.
1437 ///
1438 /// # Parameters
1439 ///
1440 /// * `other` - The other predicate to combine with. **Note: This parameter
1441 /// is passed by value and will transfer ownership.** If you need to
1442 /// preserve the original predicate, clone it first (if it implements
1443 /// `Clone`). Can be:
1444 /// - A closure: `|x: &T| -> bool`
1445 /// - A function pointer: `fn(&T) -> bool`
1446 /// - A `BoxPredicate<T>`
1447 /// - Another `RcPredicate<T>` (will be moved)
1448 /// - An `ArcPredicate<T>`
1449 /// - Any type implementing `Predicate<T>`
1450 ///
1451 /// # Returns
1452 ///
1453 /// A new `RcPredicate` representing the logical NOR.
1454 ///
1455 /// # Examples
1456 ///
1457 /// ```rust
1458 /// use prism3_function::predicate::{Predicate, RcPredicate};
1459 ///
1460 /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
1461 /// let is_even = |x: &i32| x % 2 == 0;
1462 ///
1463 /// let nor = is_positive.nor(is_even);
1464 /// assert!(nor.test(&-3)); // !(false || false) = true
1465 /// assert!(!nor.test(&4)); // !(true || true) = false
1466 /// assert!(!nor.test(&3)); // !(true || false) = false
1467 ///
1468 /// // Original predicate remains usable
1469 /// assert!(is_positive.test(&5));
1470 /// ```
1471 pub fn nor<P>(&self, other: P) -> RcPredicate<T>
1472 where
1473 P: Predicate<T> + 'static,
1474 {
1475 let self_fn = Rc::clone(&self.function);
1476 RcPredicate {
1477 function: Rc::new(move |value: &T| !(self_fn(value) || other.test(value))),
1478 name: None,
1479 }
1480 }
1481
1482 /// Converts this predicate to a `BoxPredicate`.
1483 ///
1484 /// # Returns
1485 ///
1486 /// A `BoxPredicate` wrapping this predicate.
1487 pub fn to_box(&self) -> BoxPredicate<T> {
1488 let self_fn = Rc::clone(&self.function);
1489 BoxPredicate {
1490 function: Box::new(move |value: &T| self_fn(value)),
1491 name: self.name.clone(),
1492 }
1493 }
1494
1495 /// Converts this predicate to a closure that can be used directly with
1496 /// standard library methods.
1497 ///
1498 /// This method creates a new closure without consuming the original
1499 /// predicate, since `RcPredicate` uses shared ownership. The returned
1500 /// closure has signature `Fn(&T) -> bool`. Since `Fn` is a subtrait of
1501 /// `FnMut`, it can be used in any context that requires either
1502 /// `Fn(&T) -> bool` or `FnMut(&T) -> bool`, making it compatible with
1503 /// methods like `Iterator::filter`, `Iterator::filter_map`,
1504 /// `Vec::retain`, and similar standard library APIs.
1505 ///
1506 /// # Returns
1507 ///
1508 /// A closure implementing `Fn(&T) -> bool` (also usable as
1509 /// `FnMut(&T) -> bool`).
1510 ///
1511 /// # Examples
1512 ///
1513 /// ## Using with `Iterator::filter` (requires `FnMut`)
1514 ///
1515 /// ```rust
1516 /// use prism3_function::predicate::{Predicate, RcPredicate};
1517 ///
1518 /// let pred = RcPredicate::new(|x: &i32| *x > 0);
1519 /// let closure = pred.to_fn();
1520 ///
1521 /// let numbers = vec![-2, -1, 0, 1, 2, 3];
1522 /// let positives: Vec<_> = numbers.iter()
1523 /// .copied()
1524 /// .filter(closure)
1525 /// .collect();
1526 /// assert_eq!(positives, vec![1, 2, 3]);
1527 ///
1528 /// // Original predicate is still usable
1529 /// assert!(pred.test(&5));
1530 /// ```
1531 ///
1532 /// ## Using with `Vec::retain` (requires `FnMut`)
1533 ///
1534 /// ```rust
1535 /// use prism3_function::predicate::{Predicate, RcPredicate};
1536 ///
1537 /// let pred = RcPredicate::new(|x: &i32| *x % 2 == 0);
1538 /// let mut numbers = vec![1, 2, 3, 4, 5, 6];
1539 /// numbers.retain(pred.to_fn());
1540 /// assert_eq!(numbers, vec![2, 4, 6]);
1541 ///
1542 /// // Original predicate is still usable
1543 /// assert!(pred.test(&2));
1544 /// ```
1545 ///
1546 /// ## Passing to functions that require `FnMut`
1547 ///
1548 /// ```rust
1549 /// use prism3_function::predicate::{Predicate, RcPredicate};
1550 ///
1551 /// fn count_matching<F>(items: &[i32], mut predicate: F) -> usize
1552 /// where
1553 /// F: FnMut(&i32) -> bool,
1554 /// {
1555 /// items.iter().filter(|x| predicate(x)).count()
1556 /// }
1557 ///
1558 /// let pred = RcPredicate::new(|x: &i32| *x > 10);
1559 /// let count = count_matching(&[5, 15, 8, 20], pred.to_fn());
1560 /// assert_eq!(count, 2);
1561 ///
1562 /// // Original predicate can be reused
1563 /// let count2 = count_matching(&[12, 3, 18], pred.to_fn());
1564 /// assert_eq!(count2, 2);
1565 /// ```
1566 pub fn to_fn(&self) -> impl Fn(&T) -> bool {
1567 let function = Rc::clone(&self.function);
1568 move |value: &T| function(value)
1569 }
1570}
1571
1572impl<T: 'static> Predicate<T> for RcPredicate<T> {
1573 fn test(&self, value: &T) -> bool {
1574 (self.function)(value)
1575 }
1576
1577 fn into_box(self) -> BoxPredicate<T> {
1578 let self_fn = self.function;
1579 BoxPredicate {
1580 function: Box::new(move |value: &T| self_fn(value)),
1581 name: self.name,
1582 }
1583 }
1584
1585 fn into_rc(self) -> RcPredicate<T> {
1586 self
1587 }
1588
1589 fn into_arc(self) -> ArcPredicate<T>
1590 where
1591 T: Send + Sync,
1592 {
1593 // RcPredicate cannot be converted to ArcPredicate because Rc is not Send.
1594 // Users should use ArcPredicate::new directly if they need thread-safety.
1595 panic!("RcPredicate cannot be converted to ArcPredicate - use ArcPredicate::new directly")
1596 }
1597
1598 fn into_fn(self) -> impl Fn(&T) -> bool {
1599 let self_fn = self.function;
1600 move |value: &T| self_fn(value)
1601 }
1602}
1603
1604impl<T> Clone for RcPredicate<T> {
1605 /// Clones this predicate.
1606 ///
1607 /// Creates a new instance that shares the underlying function with the
1608 /// original, allowing multiple references to the same predicate logic.
1609 fn clone(&self) -> Self {
1610 Self {
1611 function: Rc::clone(&self.function),
1612 name: self.name.clone(),
1613 }
1614 }
1615}
1616
1617impl<T> Display for RcPredicate<T> {
1618 /// Implements Display trait for RcPredicate
1619 ///
1620 /// Shows the predicate name if available, or "unnamed" as default.
1621 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1622 write!(
1623 f,
1624 "RcPredicate({})",
1625 self.name.as_deref().unwrap_or("unnamed")
1626 )
1627 }
1628}
1629
1630impl<T> Debug for RcPredicate<T> {
1631 /// Implements Debug trait for RcPredicate
1632 ///
1633 /// Shows the predicate name in debug struct format.
1634 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1635 f.debug_struct("RcPredicate")
1636 .field("name", &self.name)
1637 .finish()
1638 }
1639}
1640
1641/// An Arc-based predicate with thread-safe shared ownership.
1642///
1643/// This type is suitable for scenarios where the predicate needs to be
1644/// shared across threads. Composition methods borrow `&self`, allowing the
1645/// original predicate to remain usable after composition.
1646///
1647/// # Examples
1648///
1649/// ```rust
1650/// use prism3_function::predicate::{Predicate, ArcPredicate};
1651///
1652/// let pred = ArcPredicate::new(|x: &i32| *x > 0);
1653/// assert!(pred.test(&5));
1654///
1655/// // Original predicate remains usable after composition
1656/// let combined = pred.and(ArcPredicate::new(|x| x % 2 == 0));
1657/// assert!(pred.test(&5)); // Still works
1658///
1659/// // Can be cloned and sent across threads
1660/// let pred_clone = pred.clone();
1661/// std::thread::spawn(move || {
1662/// assert!(pred_clone.test(&10));
1663/// }).join().unwrap();
1664/// ```
1665///
1666/// # Author
1667///
1668/// Haixing Hu
1669pub struct ArcPredicate<T> {
1670 function: Arc<dyn Fn(&T) -> bool + Send + Sync>,
1671 name: Option<String>,
1672}
1673
1674impl<T: 'static> ArcPredicate<T> {
1675 /// Creates a new `ArcPredicate` from a closure.
1676 ///
1677 /// # Parameters
1678 ///
1679 /// * `f` - The closure to wrap.
1680 ///
1681 /// # Returns
1682 ///
1683 /// A new `ArcPredicate` instance.
1684 pub fn new<F>(f: F) -> Self
1685 where
1686 F: Fn(&T) -> bool + Send + Sync + 'static,
1687 {
1688 Self {
1689 function: Arc::new(f),
1690 name: None,
1691 }
1692 }
1693
1694 /// Creates a named `ArcPredicate` from a closure.
1695 ///
1696 /// # Parameters
1697 ///
1698 /// * `name` - The name for this predicate.
1699 /// * `f` - The closure to wrap.
1700 ///
1701 /// # Returns
1702 ///
1703 /// A new named `ArcPredicate` instance.
1704 pub fn new_with_name<F>(name: &str, f: F) -> Self
1705 where
1706 F: Fn(&T) -> bool + Send + Sync + 'static,
1707 {
1708 Self {
1709 function: Arc::new(f),
1710 name: Some(name.to_string()),
1711 }
1712 }
1713
1714 /// Creates a predicate that always returns `true`.
1715 ///
1716 /// # Returns
1717 ///
1718 /// A new `ArcPredicate` that always returns `true`.
1719 ///
1720 /// # Examples
1721 ///
1722 /// ```rust
1723 /// use prism3_function::predicate::{Predicate, ArcPredicate};
1724 ///
1725 /// let pred: ArcPredicate<i32> = ArcPredicate::always_true();
1726 /// assert!(pred.test(&42));
1727 /// assert!(pred.test(&-1));
1728 /// assert!(pred.test(&0));
1729 /// ```
1730 pub fn always_true() -> Self {
1731 Self {
1732 function: Arc::new(|_| true),
1733 name: Some(ALWAYS_TRUE_NAME.to_string()),
1734 }
1735 }
1736
1737 /// Creates a predicate that always returns `false`.
1738 ///
1739 /// # Returns
1740 ///
1741 /// A new `ArcPredicate` that always returns `false`.
1742 ///
1743 /// # Examples
1744 ///
1745 /// ```rust
1746 /// use prism3_function::predicate::{Predicate, ArcPredicate};
1747 ///
1748 /// let pred: ArcPredicate<i32> = ArcPredicate::always_false();
1749 /// assert!(!pred.test(&42));
1750 /// assert!(!pred.test(&-1));
1751 /// assert!(!pred.test(&0));
1752 /// ```
1753 pub fn always_false() -> Self {
1754 Self {
1755 function: Arc::new(|_| false),
1756 name: Some(ALWAYS_FALSE_NAME.to_string()),
1757 }
1758 }
1759
1760 /// Returns the name of this predicate, if set.
1761 ///
1762 /// # Returns
1763 ///
1764 /// An `Option` containing the predicate's name.
1765 pub fn name(&self) -> Option<&str> {
1766 self.name.as_deref()
1767 }
1768
1769 /// Sets the name of this predicate.
1770 ///
1771 /// # Parameters
1772 ///
1773 /// * `name` - The new name for this predicate.
1774 pub fn set_name(&mut self, name: &str) {
1775 self.name = Some(name.to_string());
1776 }
1777
1778 /// Returns a predicate that represents the logical AND of this predicate
1779 /// and another.
1780 ///
1781 /// # Parameters
1782 ///
1783 /// * `other` - The other predicate to combine with. **Note: This parameter
1784 /// is passed by value and will transfer ownership.** If you need to
1785 /// preserve the original predicate, clone it first (if it implements
1786 /// `Clone`). Can be:
1787 /// - A closure: `|x: &T| -> bool`
1788 /// - A function pointer: `fn(&T) -> bool`
1789 /// - A `BoxPredicate<T>`
1790 /// - An `RcPredicate<T>`
1791 /// - Another `ArcPredicate<T>` (will be moved)
1792 /// - Any type implementing `Predicate<T> + Send + Sync`
1793 ///
1794 /// # Returns
1795 ///
1796 /// A new `ArcPredicate` representing the logical AND.
1797 ///
1798 /// # Examples
1799 ///
1800 /// ```rust
1801 /// use prism3_function::predicate::{Predicate, ArcPredicate};
1802 /// use std::thread;
1803 ///
1804 /// let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
1805 /// let is_even = |x: &i32| x % 2 == 0;
1806 ///
1807 /// let combined = is_positive.and(is_even);
1808 ///
1809 /// // can be used across threads
1810 /// let handle = thread::spawn(move || {
1811 /// combined.test(&4)
1812 /// });
1813 ///
1814 /// assert!(handle.join().unwrap());
1815 /// assert!(is_positive.test(&5)); // original predicate still usable
1816 /// ```
1817 pub fn and<P>(&self, other: P) -> ArcPredicate<T>
1818 where
1819 T: Send + Sync,
1820 P: Predicate<T> + Send + Sync + 'static,
1821 {
1822 let self_fn = Arc::clone(&self.function);
1823 ArcPredicate {
1824 function: Arc::new(move |value: &T| self_fn(value) && other.test(value)),
1825 name: None,
1826 }
1827 }
1828
1829 /// Returns a predicate that represents the logical OR of this predicate
1830 /// and another.
1831 ///
1832 /// # Parameters
1833 ///
1834 /// * `other` - The other predicate to combine with. **Note: This parameter
1835 /// is passed by value and will transfer ownership.** If you need to
1836 /// preserve the original predicate, clone it first (if it implements
1837 /// `Clone`). Can be:
1838 /// - A closure: `|x: &T| -> bool`
1839 /// - A function pointer: `fn(&T) -> bool`
1840 /// - A `BoxPredicate<T>`
1841 /// - An `RcPredicate<T>`
1842 /// - Another `ArcPredicate<T>` (will be moved)
1843 /// - Any type implementing `Predicate<T> + Send + Sync`
1844 ///
1845 /// # Returns
1846 ///
1847 /// A new `ArcPredicate` representing the logical OR. Thread-safe.
1848 ///
1849 /// # Examples
1850 ///
1851 /// ```rust
1852 /// use prism3_function::predicate::{Predicate, ArcPredicate};
1853 ///
1854 /// let is_negative = ArcPredicate::new(|x: &i32| *x < 0);
1855 /// let is_large = |x: &i32| *x > 100;
1856 ///
1857 /// let combined = is_negative.or(is_large);
1858 /// assert!(combined.test(&-5));
1859 /// assert!(combined.test(&150));
1860 /// assert!(is_negative.test(&-10)); // original predicate still usable
1861 /// ```
1862 pub fn or<P>(&self, other: P) -> ArcPredicate<T>
1863 where
1864 T: Send + Sync,
1865 P: Predicate<T> + Send + Sync + 'static,
1866 {
1867 let self_fn = Arc::clone(&self.function);
1868 ArcPredicate {
1869 function: Arc::new(move |value: &T| self_fn(value) || other.test(value)),
1870 name: None,
1871 }
1872 }
1873
1874 /// Returns a predicate that represents the logical negation of this
1875 /// predicate.
1876 ///
1877 /// # Returns
1878 ///
1879 /// A new `ArcPredicate` representing the logical negation.
1880 #[allow(clippy::should_implement_trait)]
1881 pub fn not(&self) -> ArcPredicate<T>
1882 where
1883 T: Send + Sync,
1884 {
1885 let self_fn = Arc::clone(&self.function);
1886 ArcPredicate {
1887 function: Arc::new(move |value: &T| !self_fn(value)),
1888 name: None,
1889 }
1890 }
1891
1892 /// Returns a predicate that represents the logical NAND (NOT AND) of this
1893 /// predicate and another.
1894 ///
1895 /// NAND returns `true` unless both predicates are `true`.
1896 /// Equivalent to `!(self AND other)`.
1897 ///
1898 /// # Parameters
1899 ///
1900 /// * `other` - The other predicate to combine with. **Note: This parameter
1901 /// is passed by value and will transfer ownership.** If you need to
1902 /// preserve the original predicate, clone it first (if it implements
1903 /// `Clone`). Accepts closures, function pointers, or any
1904 /// `Predicate<T> + Send + Sync` implementation.
1905 ///
1906 /// # Returns
1907 ///
1908 /// A new `ArcPredicate` representing the logical NAND. Thread-safe.
1909 ///
1910 /// # Examples
1911 ///
1912 /// ```rust
1913 /// use prism3_function::predicate::{Predicate, ArcPredicate};
1914 ///
1915 /// let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
1916 /// let is_even = |x: &i32| x % 2 == 0;
1917 ///
1918 /// let nand = is_positive.nand(is_even);
1919 /// assert!(nand.test(&3)); // !(true && false) = true
1920 /// assert!(!nand.test(&4)); // !(true && true) = false
1921 /// ```
1922 pub fn nand<P>(&self, other: P) -> ArcPredicate<T>
1923 where
1924 T: Send + Sync,
1925 P: Predicate<T> + Send + Sync + 'static,
1926 {
1927 let self_fn = Arc::clone(&self.function);
1928 ArcPredicate {
1929 function: Arc::new(move |value: &T| !(self_fn(value) && other.test(value))),
1930 name: None,
1931 }
1932 }
1933
1934 /// Returns a predicate that represents the logical XOR (exclusive OR) of
1935 /// this predicate and another.
1936 ///
1937 /// XOR returns `true` if exactly one of the predicates is `true`.
1938 ///
1939 /// # Parameters
1940 ///
1941 /// * `other` - The other predicate to combine with. **Note: This parameter
1942 /// is passed by value and will transfer ownership.** If you need to
1943 /// preserve the original predicate, clone it first (if it implements
1944 /// `Clone`).
1945 ///
1946 /// # Returns
1947 ///
1948 /// A new `ArcPredicate` representing the logical XOR.
1949 pub fn xor<P>(&self, other: P) -> ArcPredicate<T>
1950 where
1951 T: Send + Sync,
1952 P: Predicate<T> + Send + Sync + 'static,
1953 {
1954 let self_fn = Arc::clone(&self.function);
1955 ArcPredicate {
1956 function: Arc::new(move |value: &T| self_fn(value) ^ other.test(value)),
1957 name: None,
1958 }
1959 }
1960
1961 /// Returns a predicate that represents the logical NOR (NOT OR) of this
1962 /// predicate and another.
1963 ///
1964 /// NOR returns `true` only when both predicates are `false`. Equivalent
1965 /// to `!(self OR other)`.
1966 ///
1967 /// # Parameters
1968 ///
1969 /// * `other` - The other predicate to combine with. **Note: This parameter
1970 /// is passed by value and will transfer ownership.** If you need to
1971 /// preserve the original predicate, clone it first (if it implements
1972 /// `Clone`). Accepts closures, function pointers, or any
1973 /// `Predicate<T> + Send + Sync` implementation.
1974 ///
1975 /// # Returns
1976 ///
1977 /// A new `ArcPredicate` representing the logical NOR. Thread-safe.
1978 ///
1979 /// # Examples
1980 ///
1981 /// ```rust
1982 /// use prism3_function::predicate::{Predicate, ArcPredicate};
1983 ///
1984 /// let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
1985 /// let is_even = |x: &i32| x % 2 == 0;
1986 ///
1987 /// let nor = is_positive.nor(is_even);
1988 /// assert!(nor.test(&-3)); // !(false || false) = true
1989 /// assert!(!nor.test(&4)); // !(true || true) = false
1990 /// assert!(!nor.test(&3)); // !(true || false) = false
1991 /// ```
1992 pub fn nor<P>(&self, other: P) -> ArcPredicate<T>
1993 where
1994 T: Send + Sync,
1995 P: Predicate<T> + Send + Sync + 'static,
1996 {
1997 let self_fn = Arc::clone(&self.function);
1998 ArcPredicate {
1999 function: Arc::new(move |value: &T| !(self_fn(value) || other.test(value))),
2000 name: None,
2001 }
2002 }
2003
2004 /// Converts this predicate to a `BoxPredicate`.
2005 ///
2006 /// # Returns
2007 ///
2008 /// A `BoxPredicate` wrapping this predicate.
2009 pub fn to_box(&self) -> BoxPredicate<T> {
2010 let self_fn = Arc::clone(&self.function);
2011 BoxPredicate {
2012 function: Box::new(move |value: &T| self_fn(value)),
2013 name: self.name.clone(),
2014 }
2015 }
2016
2017 /// Converts this predicate to an `RcPredicate`.
2018 ///
2019 /// # Returns
2020 ///
2021 /// An `RcPredicate` wrapping this predicate.
2022 pub fn to_rc(&self) -> RcPredicate<T> {
2023 let self_fn = Arc::clone(&self.function);
2024 RcPredicate {
2025 function: Rc::new(move |value: &T| self_fn(value)),
2026 name: self.name.clone(),
2027 }
2028 }
2029
2030 /// Converts this predicate to a closure that can be used directly with
2031 /// standard library methods.
2032 ///
2033 /// This method creates a new closure without consuming the original
2034 /// predicate, since `ArcPredicate` uses shared ownership. The returned
2035 /// closure has signature `Fn(&T) -> bool + Send + Sync` and is
2036 /// thread-safe. Since `Fn` is a subtrait of `FnMut`, it can be used in
2037 /// any context that requires either `Fn(&T) -> bool` or
2038 /// `FnMut(&T) -> bool`, making it compatible with methods like
2039 /// `Iterator::filter`, `Iterator::filter_map`, `Vec::retain`, and
2040 /// similar standard library APIs.
2041 ///
2042 /// # Returns
2043 ///
2044 /// A closure implementing `Fn(&T) -> bool + Send + Sync` (also usable
2045 /// as `FnMut(&T) -> bool`).
2046 ///
2047 /// # Examples
2048 ///
2049 /// ## Using with `Iterator::filter` (requires `FnMut`)
2050 ///
2051 /// ```rust
2052 /// use prism3_function::predicate::{Predicate, ArcPredicate};
2053 ///
2054 /// let pred = ArcPredicate::new(|x: &i32| *x > 0);
2055 /// let closure = pred.to_fn();
2056 ///
2057 /// let numbers = vec![-2, -1, 0, 1, 2, 3];
2058 /// let positives: Vec<_> = numbers.iter()
2059 /// .copied()
2060 /// .filter(closure)
2061 /// .collect();
2062 /// assert_eq!(positives, vec![1, 2, 3]);
2063 ///
2064 /// // Original predicate is still usable
2065 /// assert!(pred.test(&5));
2066 /// ```
2067 ///
2068 /// ## Using with `Vec::retain` (requires `FnMut`)
2069 ///
2070 /// ```rust
2071 /// use prism3_function::predicate::{Predicate, ArcPredicate};
2072 ///
2073 /// let pred = ArcPredicate::new(|x: &i32| *x % 2 == 0);
2074 /// let mut numbers = vec![1, 2, 3, 4, 5, 6];
2075 /// numbers.retain(pred.to_fn());
2076 /// assert_eq!(numbers, vec![2, 4, 6]);
2077 ///
2078 /// // Original predicate is still usable
2079 /// assert!(pred.test(&2));
2080 /// ```
2081 ///
2082 /// ## Passing to functions that require `FnMut`
2083 ///
2084 /// ```rust
2085 /// use prism3_function::predicate::{Predicate, ArcPredicate};
2086 ///
2087 /// fn count_matching<F>(items: &[i32], mut predicate: F) -> usize
2088 /// where
2089 /// F: FnMut(&i32) -> bool,
2090 /// {
2091 /// items.iter().filter(|x| predicate(x)).count()
2092 /// }
2093 ///
2094 /// let pred = ArcPredicate::new(|x: &i32| *x > 10);
2095 /// let count = count_matching(&[5, 15, 8, 20], pred.to_fn());
2096 /// assert_eq!(count, 2);
2097 ///
2098 /// // Original predicate can be reused
2099 /// let count2 = count_matching(&[12, 3, 18], pred.to_fn());
2100 /// assert_eq!(count2, 2);
2101 /// ```
2102 ///
2103 /// ## Thread-safe usage
2104 ///
2105 /// ```rust
2106 /// use prism3_function::predicate::{Predicate, ArcPredicate};
2107 /// use std::thread;
2108 ///
2109 /// let pred = ArcPredicate::new(|x: &i32| *x > 0);
2110 /// let closure = pred.to_fn();
2111 ///
2112 /// // Closure can be sent across threads
2113 /// let handle = thread::spawn(move || {
2114 /// let numbers = vec![-2, -1, 0, 1, 2, 3];
2115 /// numbers.iter().copied().filter(closure).count()
2116 /// });
2117 ///
2118 /// assert_eq!(handle.join().unwrap(), 3);
2119 /// // Original predicate is still usable
2120 /// assert!(pred.test(&5));
2121 /// ```
2122 pub fn to_fn(&self) -> impl Fn(&T) -> bool + Send + Sync
2123 where
2124 T: Send + Sync,
2125 {
2126 let self_fn = Arc::clone(&self.function);
2127 move |value: &T| self_fn(value)
2128 }
2129}
2130
2131impl<T: 'static> Predicate<T> for ArcPredicate<T> {
2132 fn test(&self, value: &T) -> bool {
2133 (self.function)(value)
2134 }
2135
2136 fn into_box(self) -> BoxPredicate<T> {
2137 let self_fn = self.function;
2138 BoxPredicate {
2139 function: Box::new(move |value: &T| self_fn(value)),
2140 name: self.name,
2141 }
2142 }
2143
2144 fn into_rc(self) -> RcPredicate<T> {
2145 let self_fn = self.function;
2146 RcPredicate {
2147 function: Rc::new(move |value: &T| self_fn(value)),
2148 name: self.name,
2149 }
2150 }
2151
2152 fn into_arc(self) -> ArcPredicate<T>
2153 where
2154 T: Send + Sync,
2155 {
2156 self
2157 }
2158
2159 fn into_fn(self) -> impl Fn(&T) -> bool {
2160 let self_fn = self.function;
2161 move |value: &T| self_fn(value)
2162 }
2163}
2164
2165impl<T> Clone for ArcPredicate<T> {
2166 /// Clones this predicate.
2167 ///
2168 /// Creates a new instance that shares the underlying function with the
2169 /// original, allowing multiple references to the same predicate logic.
2170 fn clone(&self) -> Self {
2171 Self {
2172 function: Arc::clone(&self.function),
2173 name: self.name.clone(),
2174 }
2175 }
2176}
2177
2178impl<T> Display for ArcPredicate<T> {
2179 /// Implements Display trait for ArcPredicate
2180 ///
2181 /// Shows the predicate name if available, or "unnamed" as default.
2182 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2183 write!(
2184 f,
2185 "ArcPredicate({})",
2186 self.name.as_deref().unwrap_or("unnamed")
2187 )
2188 }
2189}
2190
2191impl<T> Debug for ArcPredicate<T> {
2192 /// Implements Debug trait for ArcPredicate
2193 ///
2194 /// Shows the predicate name in debug struct format.
2195 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2196 f.debug_struct("ArcPredicate")
2197 .field("name", &self.name)
2198 .finish()
2199 }
2200}
2201
2202// Blanket implementation for all closures that match Fn(&T) -> bool
2203impl<T: 'static, F> Predicate<T> for F
2204where
2205 F: Fn(&T) -> bool + 'static,
2206{
2207 fn test(&self, value: &T) -> bool {
2208 self(value)
2209 }
2210
2211 fn into_box(self) -> BoxPredicate<T> {
2212 BoxPredicate::new(self)
2213 }
2214
2215 fn into_rc(self) -> RcPredicate<T> {
2216 RcPredicate::new(self)
2217 }
2218
2219 fn into_arc(self) -> ArcPredicate<T>
2220 where
2221 Self: Send + Sync,
2222 T: Send + Sync,
2223 {
2224 ArcPredicate::new(self)
2225 }
2226
2227 fn into_fn(self) -> impl Fn(&T) -> bool {
2228 self
2229 }
2230}
2231
2232/// Extension trait providing logical composition methods for closures.
2233///
2234/// This trait is automatically implemented for all closures and function
2235/// pointers that match `Fn(&T) -> bool`, enabling method chaining starting
2236/// from a closure.
2237///
2238/// # Examples
2239///
2240/// ```rust
2241/// use prism3_function::predicate::{Predicate, FnPredicateOps};
2242///
2243/// let is_positive = |x: &i32| *x > 0;
2244/// let is_even = |x: &i32| x % 2 == 0;
2245///
2246/// // Combine predicates using extension methods
2247/// let pred = is_positive.and(is_even);
2248/// assert!(pred.test(&4));
2249/// assert!(!pred.test(&3));
2250/// ```
2251///
2252/// # Author
2253///
2254/// Haixing Hu
2255pub trait FnPredicateOps<T>: Fn(&T) -> bool + Sized + 'static {
2256 /// Returns a predicate that represents the logical AND of this predicate
2257 /// and another.
2258 ///
2259 /// # Parameters
2260 ///
2261 /// * `other` - The other predicate to combine with. **Note: This parameter
2262 /// is passed by value and will transfer ownership.** If you need to
2263 /// preserve the original predicate, clone it first (if it implements
2264 /// `Clone`). Can be:
2265 /// - Another closure
2266 /// - A function pointer
2267 /// - A `BoxPredicate<T>`, `RcPredicate<T>`, or `ArcPredicate<T>`
2268 ///
2269 /// # Returns
2270 ///
2271 /// A `BoxPredicate` representing the logical AND.
2272 ///
2273 /// # Examples
2274 ///
2275 /// ```rust
2276 /// use prism3_function::predicate::{Predicate, FnPredicateOps};
2277 ///
2278 /// let is_positive = |x: &i32| *x > 0;
2279 /// let is_even = |x: &i32| x % 2 == 0;
2280 ///
2281 /// let combined = is_positive.and(is_even);
2282 /// assert!(combined.test(&4));
2283 /// assert!(!combined.test(&3));
2284 /// ```
2285 fn and<P>(self, other: P) -> BoxPredicate<T>
2286 where
2287 P: Predicate<T> + 'static,
2288 T: 'static,
2289 {
2290 BoxPredicate::new(move |value: &T| self.test(value) && other.test(value))
2291 }
2292
2293 /// Returns a predicate that represents the logical OR of this predicate
2294 /// and another.
2295 ///
2296 /// # Parameters
2297 ///
2298 /// * `other` - The other predicate to combine with. **Note: This parameter
2299 /// is passed by value and will transfer ownership.** If you need to
2300 /// preserve the original predicate, clone it first (if it implements
2301 /// `Clone`). Can be:
2302 /// - Another closure
2303 /// - A function pointer
2304 /// - A `BoxPredicate<T>`, `RcPredicate<T>`, or `ArcPredicate<T>`
2305 /// - Any type implementing `Predicate<T>`
2306 ///
2307 /// # Returns
2308 ///
2309 /// A `BoxPredicate` representing the logical OR.
2310 ///
2311 /// # Examples
2312 ///
2313 /// ```rust
2314 /// use prism3_function::predicate::{Predicate, FnPredicateOps};
2315 ///
2316 /// let is_negative = |x: &i32| *x < 0;
2317 /// let is_large = |x: &i32| *x > 100;
2318 ///
2319 /// let combined = is_negative.or(is_large);
2320 /// assert!(combined.test(&-5));
2321 /// assert!(combined.test(&150));
2322 /// assert!(!combined.test(&50));
2323 /// ```
2324 fn or<P>(self, other: P) -> BoxPredicate<T>
2325 where
2326 P: Predicate<T> + 'static,
2327 T: 'static,
2328 {
2329 BoxPredicate::new(move |value: &T| self.test(value) || other.test(value))
2330 }
2331
2332 /// Returns a predicate that represents the logical negation of this
2333 /// predicate.
2334 ///
2335 /// # Returns
2336 ///
2337 /// A `BoxPredicate` representing the logical negation.
2338 fn not(self) -> BoxPredicate<T>
2339 where
2340 T: 'static,
2341 {
2342 BoxPredicate::new(move |value: &T| !self.test(value))
2343 }
2344
2345 /// Returns a predicate that represents the logical NAND (NOT AND) of this
2346 /// predicate and another.
2347 ///
2348 /// NAND returns `true` unless both predicates are `true`.
2349 /// Equivalent to `!(self AND other)`.
2350 ///
2351 /// # Parameters
2352 ///
2353 /// * `other` - The other predicate to combine with. **Note: This parameter
2354 /// is passed by value and will transfer ownership.** If you need to
2355 /// preserve the original predicate, clone it first (if it implements
2356 /// `Clone`). Accepts closures, function pointers, or any
2357 /// `Predicate<T>` implementation.
2358 ///
2359 /// # Returns
2360 ///
2361 /// A `BoxPredicate` representing the logical NAND.
2362 ///
2363 /// # Examples
2364 ///
2365 /// ```rust
2366 /// use prism3_function::predicate::{Predicate, FnPredicateOps};
2367 ///
2368 /// let is_positive = |x: &i32| *x > 0;
2369 /// let is_even = |x: &i32| x % 2 == 0;
2370 ///
2371 /// let nand = is_positive.nand(is_even);
2372 /// assert!(nand.test(&3)); // !(true && false) = true
2373 /// assert!(!nand.test(&4)); // !(true && true) = false
2374 /// ```
2375 fn nand<P>(self, other: P) -> BoxPredicate<T>
2376 where
2377 P: Predicate<T> + 'static,
2378 T: 'static,
2379 {
2380 BoxPredicate::new(move |value: &T| !(self.test(value) && other.test(value)))
2381 }
2382
2383 /// Returns a predicate that represents the logical XOR (exclusive OR) of
2384 /// this predicate and another.
2385 ///
2386 /// XOR returns `true` if exactly one of the predicates is `true`.
2387 ///
2388 /// # Parameters
2389 ///
2390 /// * `other` - The other predicate to combine with. **Note: This parameter
2391 /// is passed by value and will transfer ownership.** If you need to
2392 /// preserve the original predicate, clone it first (if it implements
2393 /// `Clone`). Accepts closures, function pointers, or any
2394 /// `Predicate<T>` implementation.
2395 ///
2396 /// # Returns
2397 ///
2398 /// A `BoxPredicate` representing the logical XOR.
2399 ///
2400 /// # Examples
2401 ///
2402 /// ```rust
2403 /// use prism3_function::predicate::{Predicate, FnPredicateOps};
2404 ///
2405 /// let is_positive = |x: &i32| *x > 0;
2406 /// let is_even = |x: &i32| x % 2 == 0;
2407 ///
2408 /// let xor = is_positive.xor(is_even);
2409 /// assert!(xor.test(&3)); // true ^ false = true
2410 /// assert!(!xor.test(&4)); // true ^ true = false
2411 /// assert!(!xor.test(&-1)); // false ^ false = false
2412 /// ```
2413 fn xor<P>(self, other: P) -> BoxPredicate<T>
2414 where
2415 P: Predicate<T> + 'static,
2416 T: 'static,
2417 {
2418 BoxPredicate::new(move |value: &T| self.test(value) ^ other.test(value))
2419 }
2420
2421 /// Returns a predicate that represents the logical NOR (NOT OR) of this
2422 /// predicate and another.
2423 ///
2424 /// NOR returns `true` only when both predicates are `false`. Equivalent
2425 /// to `!(self OR other)`.
2426 ///
2427 /// # Parameters
2428 ///
2429 /// * `other` - The other predicate to combine with. **Note: This parameter
2430 /// is passed by value and will transfer ownership.** If you need to
2431 /// preserve the original predicate, clone it first (if it implements
2432 /// `Clone`). Accepts closures, function pointers, or any
2433 /// `Predicate<T>` implementation.
2434 ///
2435 /// # Returns
2436 ///
2437 /// A `BoxPredicate` representing the logical NOR.
2438 ///
2439 /// # Examples
2440 ///
2441 /// ```rust
2442 /// use prism3_function::predicate::{Predicate, FnPredicateOps};
2443 ///
2444 /// let is_positive = |x: &i32| *x > 0;
2445 /// let is_even = |x: &i32| x % 2 == 0;
2446 ///
2447 /// let nor = is_positive.nor(is_even);
2448 /// assert!(nor.test(&-3)); // !(false || false) = true
2449 /// assert!(!nor.test(&4)); // !(true || true) = false
2450 /// assert!(!nor.test(&3)); // !(true || false) = false
2451 /// ```
2452 fn nor<P>(self, other: P) -> BoxPredicate<T>
2453 where
2454 P: Predicate<T> + 'static,
2455 T: 'static,
2456 {
2457 BoxPredicate::new(move |value: &T| !(self.test(value) || other.test(value)))
2458 }
2459}
2460
2461// Blanket implementation for all closures
2462impl<T, F> FnPredicateOps<T> for F where F: Fn(&T) -> bool + 'static {}