Skip to main content

qubit_lock/monitor/
arc_mock_monitor.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//! Arc-wrapped mock monitor.
11
12use std::{
13    ops::Deref,
14    sync::Arc,
15    time::Duration,
16};
17
18#[cfg(feature = "async")]
19use super::{
20    AsyncConditionWaiter,
21    AsyncMonitorFuture,
22    AsyncNotificationWaiter,
23    AsyncTimeoutConditionWaiter,
24    AsyncTimeoutNotificationWaiter,
25};
26use super::{
27    ConditionWaiter,
28    MockMonitor,
29    NotificationWaiter,
30    Notifier,
31    TimeoutConditionWaiter,
32    TimeoutNotificationWaiter,
33    WaitTimeoutResult,
34    WaitTimeoutStatus,
35};
36
37/// Cloneable handle around a [`MockMonitor`].
38pub struct ArcMockMonitor<T> {
39    /// Shared mock monitor.
40    inner: Arc<MockMonitor<T>>,
41}
42
43impl<T> ArcMockMonitor<T> {
44    /// Creates an Arc-wrapped mock monitor.
45    ///
46    /// # Arguments
47    ///
48    /// * `state` - Initial protected state.
49    ///
50    /// # Returns
51    ///
52    /// A cloneable mock monitor handle.
53    pub fn new(state: T) -> Self {
54        Self {
55            inner: Arc::new(MockMonitor::new(state)),
56        }
57    }
58
59    /// Returns the current mock elapsed time.
60    pub fn elapsed(&self) -> Duration {
61        self.inner.elapsed()
62    }
63
64    /// Sets the current mock elapsed time.
65    ///
66    /// # Arguments
67    ///
68    /// * `elapsed` - New mock elapsed time.
69    pub fn set_elapsed(&self, elapsed: Duration) {
70        self.inner.set_elapsed(elapsed);
71    }
72
73    /// Advances mock elapsed time.
74    ///
75    /// # Arguments
76    ///
77    /// * `duration` - Duration added to current mock elapsed time.
78    pub fn advance(&self, duration: Duration) {
79        self.inner.advance(duration);
80    }
81
82    /// Resets mock elapsed time to zero.
83    pub fn reset_elapsed(&self) {
84        self.inner.reset_elapsed();
85    }
86
87    /// Reads protected state.
88    pub fn read<R, F>(&self, f: F) -> R
89    where
90        F: FnOnce(&T) -> R,
91    {
92        self.inner.read(f)
93    }
94
95    /// Mutates protected state without notifying.
96    pub fn write<R, F>(&self, f: F) -> R
97    where
98        F: FnOnce(&mut T) -> R,
99    {
100        self.inner.write(f)
101    }
102
103    /// Mutates protected state and wakes one waiter.
104    pub fn write_notify_one<R, F>(&self, f: F) -> R
105    where
106        F: FnOnce(&mut T) -> R,
107    {
108        self.inner.write_notify_one(f)
109    }
110
111    /// Mutates protected state and wakes all waiters.
112    pub fn write_notify_all<R, F>(&self, f: F) -> R
113    where
114        F: FnOnce(&mut T) -> R,
115    {
116        self.inner.write_notify_all(f)
117    }
118
119    /// Wakes one waiter.
120    pub fn notify_one(&self) {
121        self.inner.notify_one();
122    }
123
124    /// Wakes all waiters.
125    pub fn notify_all(&self) {
126        self.inner.notify_all();
127    }
128}
129
130impl<T> Notifier for ArcMockMonitor<T> {
131    /// Wakes one waiter.
132    fn notify_one(&self) {
133        Self::notify_one(self);
134    }
135
136    /// Wakes all waiters.
137    fn notify_all(&self) {
138        Self::notify_all(self);
139    }
140}
141
142impl<T> NotificationWaiter for ArcMockMonitor<T> {
143    /// Blocks until notification.
144    fn wait(&self) {
145        self.inner.wait();
146    }
147}
148
149impl<T> TimeoutNotificationWaiter for ArcMockMonitor<T> {
150    /// Blocks until notification or mock timeout.
151    fn wait_for(&self, timeout: Duration) -> WaitTimeoutStatus {
152        self.inner.wait_for(timeout)
153    }
154}
155
156impl<T> ConditionWaiter for ArcMockMonitor<T> {
157    type State = T;
158
159    /// Blocks until the predicate becomes true, then runs the action.
160    fn wait_until<R, P, F>(&self, predicate: P, action: F) -> R
161    where
162        P: FnMut(&Self::State) -> bool,
163        F: FnOnce(&mut Self::State) -> R,
164    {
165        self.inner.wait_until(predicate, action)
166    }
167
168    /// Blocks while the predicate remains true, then runs the action.
169    fn wait_while<R, P, F>(&self, predicate: P, action: F) -> R
170    where
171        P: FnMut(&Self::State) -> bool,
172        F: FnOnce(&mut Self::State) -> R,
173    {
174        self.inner.wait_while(predicate, action)
175    }
176}
177
178impl<T> TimeoutConditionWaiter for ArcMockMonitor<T> {
179    /// Blocks until the predicate becomes true or mock timeout expires.
180    fn wait_until_for<R, P, F>(
181        &self,
182        timeout: Duration,
183        predicate: P,
184        action: F,
185    ) -> WaitTimeoutResult<R>
186    where
187        P: FnMut(&Self::State) -> bool,
188        F: FnOnce(&mut Self::State) -> R,
189    {
190        self.inner.wait_until_for(timeout, predicate, action)
191    }
192
193    /// Blocks while the predicate remains true or until mock timeout expires.
194    fn wait_while_for<R, P, F>(
195        &self,
196        timeout: Duration,
197        predicate: P,
198        action: F,
199    ) -> WaitTimeoutResult<R>
200    where
201        P: FnMut(&Self::State) -> bool,
202        F: FnOnce(&mut Self::State) -> R,
203    {
204        self.inner.wait_while_for(timeout, predicate, action)
205    }
206}
207
208#[cfg(feature = "async")]
209impl<T: Send> AsyncNotificationWaiter for ArcMockMonitor<T> {
210    /// Returns a future that resolves after an async notification.
211    fn async_wait<'a>(&'a self) -> AsyncMonitorFuture<'a, ()> {
212        self.inner.async_wait()
213    }
214}
215
216#[cfg(feature = "async")]
217impl<T: Send> AsyncTimeoutNotificationWaiter for ArcMockMonitor<T> {
218    /// Returns a future that resolves after notification or mock timeout.
219    fn async_wait_for<'a>(
220        &'a self,
221        timeout: Duration,
222    ) -> AsyncMonitorFuture<'a, WaitTimeoutStatus> {
223        self.inner.async_wait_for(timeout)
224    }
225}
226
227#[cfg(feature = "async")]
228impl<T: Send> AsyncConditionWaiter for ArcMockMonitor<T> {
229    type State = T;
230
231    /// Returns a future that waits until the predicate becomes true.
232    fn async_wait_until<'a, R, P, F>(&'a self, predicate: P, action: F) -> AsyncMonitorFuture<'a, R>
233    where
234        R: Send + 'a,
235        P: FnMut(&Self::State) -> bool + Send + 'a,
236        F: FnOnce(&mut Self::State) -> R + Send + 'a,
237    {
238        self.inner.async_wait_until(predicate, action)
239    }
240
241    /// Returns a future that waits while the predicate remains true.
242    fn async_wait_while<'a, R, P, F>(&'a self, predicate: P, action: F) -> AsyncMonitorFuture<'a, R>
243    where
244        R: Send + 'a,
245        P: FnMut(&Self::State) -> bool + Send + 'a,
246        F: FnOnce(&mut Self::State) -> R + Send + 'a,
247    {
248        self.inner.async_wait_while(predicate, action)
249    }
250}
251
252#[cfg(feature = "async")]
253impl<T: Send> AsyncTimeoutConditionWaiter for ArcMockMonitor<T> {
254    /// Returns a future that waits until the predicate becomes true or times out.
255    fn async_wait_until_for<'a, R, P, F>(
256        &'a self,
257        timeout: Duration,
258        predicate: P,
259        action: F,
260    ) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
261    where
262        R: Send + 'a,
263        P: FnMut(&Self::State) -> bool + Send + 'a,
264        F: FnOnce(&mut Self::State) -> R + Send + 'a,
265    {
266        self.inner.async_wait_until_for(timeout, predicate, action)
267    }
268
269    /// Returns a future that waits while the predicate remains true or times out.
270    fn async_wait_while_for<'a, R, P, F>(
271        &'a self,
272        timeout: Duration,
273        predicate: P,
274        action: F,
275    ) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
276    where
277        R: Send + 'a,
278        P: FnMut(&Self::State) -> bool + Send + 'a,
279        F: FnOnce(&mut Self::State) -> R + Send + 'a,
280    {
281        self.inner.async_wait_while_for(timeout, predicate, action)
282    }
283}
284
285impl<T> AsRef<MockMonitor<T>> for ArcMockMonitor<T> {
286    /// Returns a reference to the wrapped mock monitor.
287    fn as_ref(&self) -> &MockMonitor<T> {
288        self.inner.as_ref()
289    }
290}
291
292impl<T> Deref for ArcMockMonitor<T> {
293    type Target = MockMonitor<T>;
294
295    /// Dereferences to the wrapped mock monitor.
296    fn deref(&self) -> &Self::Target {
297        self.inner.as_ref()
298    }
299}
300
301impl<T> Clone for ArcMockMonitor<T> {
302    /// Clones this shared mock monitor handle.
303    fn clone(&self) -> Self {
304        Self {
305            inner: self.inner.clone(),
306        }
307    }
308}
309
310impl<T> From<T> for ArcMockMonitor<T> {
311    /// Creates an Arc-wrapped mock monitor from an initial state value.
312    fn from(value: T) -> Self {
313        Self::new(value)
314    }
315}
316
317impl<T: Default> Default for ArcMockMonitor<T> {
318    /// Creates an Arc-wrapped mock monitor containing `T::default()`.
319    fn default() -> Self {
320        Self::new(T::default())
321    }
322}