Skip to main content

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