Skip to main content

qubit_function/testers/stateful_tester/
arc_stateful_tester.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//! Defines the `ArcStatefulTester` public type.
11
12use std::ops::Not;
13
14use parking_lot::Mutex;
15
16use super::{
17    Arc,
18    StatefulTester,
19    box_stateful_tester::BoxStatefulTester,
20    rc_stateful_tester::RcStatefulTester,
21};
22
23type ArcStatefulTesterFn = Arc<Mutex<dyn FnMut() -> bool + Send + 'static>>;
24
25/// A thread-safe shared stateful tester backed by `Arc<Mutex<_>>`.
26///
27/// Clones of an `ArcStatefulTester` share the same mutable closure state and
28/// can be moved across threads.
29pub struct ArcStatefulTester {
30    pub(super) function: ArcStatefulTesterFn,
31}
32
33impl ArcStatefulTester {
34    /// Creates a new thread-safe shared stateful tester.
35    #[inline]
36    pub fn new<F>(f: F) -> Self
37    where
38        F: FnMut() -> bool + Send + 'static,
39    {
40        ArcStatefulTester {
41            function: Arc::new(Mutex::new(f)),
42        }
43    }
44
45    /// Combines this tester with another stateful tester using logical AND.
46    #[inline]
47    pub fn and<T>(&self, mut next: T) -> ArcStatefulTester
48    where
49        T: StatefulTester + Send + 'static,
50    {
51        let self_fn = Arc::clone(&self.function);
52        ArcStatefulTester::new(move || {
53            let matched = (self_fn.lock())();
54            matched && next.test()
55        })
56    }
57
58    /// Combines this tester with another stateful tester using logical OR.
59    #[inline]
60    pub fn or<T>(&self, mut next: T) -> ArcStatefulTester
61    where
62        T: StatefulTester + Send + 'static,
63    {
64        let self_fn = Arc::clone(&self.function);
65        ArcStatefulTester::new(move || {
66            let matched = (self_fn.lock())();
67            matched || next.test()
68        })
69    }
70
71    /// Combines this tester with another stateful tester using logical NAND.
72    #[inline]
73    pub fn nand<T>(&self, mut next: T) -> ArcStatefulTester
74    where
75        T: StatefulTester + Send + 'static,
76    {
77        let self_fn = Arc::clone(&self.function);
78        ArcStatefulTester::new(move || {
79            let matched = (self_fn.lock())();
80            !(matched && next.test())
81        })
82    }
83
84    /// Combines this tester with another stateful tester using logical XOR.
85    #[inline]
86    pub fn xor<T>(&self, mut next: T) -> ArcStatefulTester
87    where
88        T: StatefulTester + Send + 'static,
89    {
90        let self_fn = Arc::clone(&self.function);
91        ArcStatefulTester::new(move || {
92            let matched = (self_fn.lock())();
93            matched ^ next.test()
94        })
95    }
96
97    /// Combines this tester with another stateful tester using logical NOR.
98    #[inline]
99    pub fn nor<T>(&self, mut next: T) -> ArcStatefulTester
100    where
101        T: StatefulTester + Send + 'static,
102    {
103        let self_fn = Arc::clone(&self.function);
104        ArcStatefulTester::new(move || {
105            let matched = (self_fn.lock())();
106            !(matched || next.test())
107        })
108    }
109}
110
111impl Clone for ArcStatefulTester {
112    #[inline]
113    fn clone(&self) -> Self {
114        ArcStatefulTester {
115            function: Arc::clone(&self.function),
116        }
117    }
118}
119
120impl Not for ArcStatefulTester {
121    type Output = ArcStatefulTester;
122
123    #[inline]
124    fn not(self) -> Self::Output {
125        let function = self.function;
126        ArcStatefulTester::new(move || !((function.lock())()))
127    }
128}
129
130impl Not for &ArcStatefulTester {
131    type Output = ArcStatefulTester;
132
133    #[inline]
134    fn not(self) -> Self::Output {
135        let function = Arc::clone(&self.function);
136        ArcStatefulTester::new(move || !((function.lock())()))
137    }
138}
139
140impl StatefulTester for ArcStatefulTester {
141    #[inline]
142    fn test(&mut self) -> bool {
143        (self.function.lock())()
144    }
145
146    #[inline]
147    fn into_box(self) -> BoxStatefulTester {
148        let function = self.function;
149        BoxStatefulTester::new(move || (function.lock())())
150    }
151
152    #[inline]
153    fn into_rc(self) -> RcStatefulTester {
154        let function = self.function;
155        RcStatefulTester::new(move || (function.lock())())
156    }
157
158    #[inline]
159    fn into_arc(self) -> ArcStatefulTester {
160        self
161    }
162}