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 {}