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