Skip to main content

qubit_function/predicates/stateful_predicate/
fn_stateful_predicate_ops.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10// qubit-style: allow explicit-imports
11//! Defines the `FnStatefulPredicateOps` public type.
12
13use super::{
14    BoxStatefulPredicate,
15    StatefulPredicate,
16};
17
18/// Extension trait providing logical composition methods for stateful closures.
19///
20/// This trait is implemented for closures and function objects matching
21/// `FnMut(&T) -> bool`, allowing direct composition into
22/// `BoxStatefulPredicate`.
23pub trait FnStatefulPredicateOps<T>: FnMut(&T) -> bool + Sized {
24    /// Returns a predicate representing logical AND with another predicate.
25    ///
26    /// This method consumes `self` and evaluates `other` only when this
27    /// closure returns `true`.
28    ///
29    /// # Parameters
30    ///
31    /// * `other` - The other predicate to combine with.
32    ///
33    /// # Returns
34    ///
35    /// A `BoxStatefulPredicate` representing logical AND.
36    #[inline]
37    fn and<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
38    where
39        Self: 'static,
40        P: StatefulPredicate<T> + 'static,
41        T: 'static,
42    {
43        BoxStatefulPredicate::new(move |value: &T| self(value) && other.test(value))
44    }
45
46    /// Returns a predicate representing logical OR with another predicate.
47    ///
48    /// This method consumes `self` and evaluates `other` only when this
49    /// closure returns `false`.
50    ///
51    /// # Parameters
52    ///
53    /// * `other` - The other predicate to combine with.
54    ///
55    /// # Returns
56    ///
57    /// A `BoxStatefulPredicate` representing logical OR.
58    #[inline]
59    fn or<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
60    where
61        Self: 'static,
62        P: StatefulPredicate<T> + 'static,
63        T: 'static,
64    {
65        BoxStatefulPredicate::new(move |value: &T| self(value) || other.test(value))
66    }
67
68    /// Returns a predicate representing logical negation.
69    ///
70    /// This method consumes `self` and returns a predicate that negates the
71    /// closure result.
72    ///
73    /// # Returns
74    ///
75    /// A `BoxStatefulPredicate` representing logical negation.
76    #[inline]
77    fn not(mut self) -> BoxStatefulPredicate<T>
78    where
79        Self: 'static,
80        T: 'static,
81    {
82        BoxStatefulPredicate::new(move |value: &T| !self(value))
83    }
84
85    /// Returns a predicate representing logical NAND with another predicate.
86    ///
87    /// NAND returns `true` unless both predicates return `true`.
88    ///
89    /// # Parameters
90    ///
91    /// * `other` - The other predicate to combine with.
92    ///
93    /// # Returns
94    ///
95    /// A `BoxStatefulPredicate` representing logical NAND.
96    #[inline]
97    fn nand<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
98    where
99        Self: 'static,
100        P: StatefulPredicate<T> + 'static,
101        T: 'static,
102    {
103        BoxStatefulPredicate::new(move |value: &T| !(self(value) && other.test(value)))
104    }
105
106    /// Returns a predicate representing logical XOR with another predicate.
107    ///
108    /// XOR evaluates both predicates and returns `true` when exactly one
109    /// predicate returns `true`.
110    ///
111    /// # Parameters
112    ///
113    /// * `other` - The other predicate to combine with.
114    ///
115    /// # Returns
116    ///
117    /// A `BoxStatefulPredicate` representing logical XOR.
118    #[inline]
119    fn xor<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
120    where
121        Self: 'static,
122        P: StatefulPredicate<T> + 'static,
123        T: 'static,
124    {
125        BoxStatefulPredicate::new(move |value: &T| self(value) ^ other.test(value))
126    }
127
128    /// Returns a predicate representing logical NOR with another predicate.
129    ///
130    /// NOR returns `true` only when both predicates return `false`.
131    ///
132    /// # Parameters
133    ///
134    /// * `other` - The other predicate to combine with.
135    ///
136    /// # Returns
137    ///
138    /// A `BoxStatefulPredicate` representing logical NOR.
139    #[inline]
140    fn nor<P>(mut self, mut other: P) -> BoxStatefulPredicate<T>
141    where
142        Self: 'static,
143        P: StatefulPredicate<T> + 'static,
144        T: 'static,
145    {
146        BoxStatefulPredicate::new(move |value: &T| !(self(value) || other.test(value)))
147    }
148}
149
150impl<T, F> FnStatefulPredicateOps<T> for F where F: FnMut(&T) -> bool {}