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    /// Blocks until a notification happens after this call starts.
130    pub fn wait(&self) {
131        <MockMonitor<T> as NotificationWaiter>::wait(self.inner.as_ref());
132    }
133
134    /// Blocks until notification or mock timeout.
135    ///
136    /// # Arguments
137    ///
138    /// * `timeout` - Maximum mock duration to wait.
139    ///
140    /// # Returns
141    ///
142    /// A status describing whether notification or timeout completed the wait.
143    pub fn wait_for(&self, timeout: Duration) -> WaitTimeoutStatus {
144        <MockMonitor<T> as TimeoutNotificationWaiter>::wait_for(self.inner.as_ref(), timeout)
145    }
146
147    /// Blocks until the predicate becomes true, then runs the action.
148    ///
149    /// # Arguments
150    ///
151    /// * `predicate` - Predicate that returns `true` when the state is ready.
152    /// * `action` - Action to run after the predicate becomes true.
153    ///
154    /// # Returns
155    ///
156    /// The value returned by `action`.
157    pub fn wait_until<R, P, F>(&self, predicate: P, action: F) -> R
158    where
159        P: FnMut(&T) -> bool,
160        F: FnOnce(&mut T) -> R,
161    {
162        <MockMonitor<T> as ConditionWaiter>::wait_until(self.inner.as_ref(), predicate, action)
163    }
164
165    /// Blocks while the predicate remains true, then runs the action.
166    ///
167    /// # Arguments
168    ///
169    /// * `predicate` - Predicate that returns `true` while waiting should continue.
170    /// * `action` - Action to run after the predicate becomes false.
171    ///
172    /// # Returns
173    ///
174    /// The value returned by `action`.
175    pub fn wait_while<R, P, F>(&self, predicate: P, action: F) -> R
176    where
177        P: FnMut(&T) -> bool,
178        F: FnOnce(&mut T) -> R,
179    {
180        <MockMonitor<T> as ConditionWaiter>::wait_while(self.inner.as_ref(), predicate, action)
181    }
182
183    /// Blocks until the predicate becomes true or mock timeout expires.
184    ///
185    /// # Arguments
186    ///
187    /// * `timeout` - Maximum mock duration to wait.
188    /// * `predicate` - Predicate that returns `true` when the state is ready.
189    /// * `action` - Action to run after the predicate becomes true.
190    ///
191    /// # Returns
192    ///
193    /// [`WaitTimeoutResult::Ready`] with the action result, or
194    /// [`WaitTimeoutResult::TimedOut`] when mock time reaches the timeout.
195    pub fn wait_until_for<R, P, F>(
196        &self,
197        timeout: Duration,
198        predicate: P,
199        action: F,
200    ) -> WaitTimeoutResult<R>
201    where
202        P: FnMut(&T) -> bool,
203        F: FnOnce(&mut T) -> R,
204    {
205        <MockMonitor<T> as TimeoutConditionWaiter>::wait_until_for(
206            self.inner.as_ref(),
207            timeout,
208            predicate,
209            action,
210        )
211    }
212
213    /// Blocks while the predicate remains true or until mock timeout expires.
214    ///
215    /// # Arguments
216    ///
217    /// * `timeout` - Maximum mock duration to wait.
218    /// * `predicate` - Predicate that returns `true` while waiting should continue.
219    /// * `action` - Action to run after the predicate becomes false.
220    ///
221    /// # Returns
222    ///
223    /// [`WaitTimeoutResult::Ready`] with the action result, or
224    /// [`WaitTimeoutResult::TimedOut`] when mock time reaches the timeout.
225    pub fn wait_while_for<R, P, F>(
226        &self,
227        timeout: Duration,
228        predicate: P,
229        action: F,
230    ) -> WaitTimeoutResult<R>
231    where
232        P: FnMut(&T) -> bool,
233        F: FnOnce(&mut T) -> R,
234    {
235        <MockMonitor<T> as TimeoutConditionWaiter>::wait_while_for(
236            self.inner.as_ref(),
237            timeout,
238            predicate,
239            action,
240        )
241    }
242
243    /// Returns a future that resolves after an async notification.
244    #[cfg(feature = "async")]
245    pub fn wait_async(&self) -> AsyncMonitorFuture<'_, ()>
246    where
247        T: Send,
248    {
249        <MockMonitor<T> as AsyncNotificationWaiter>::wait_async(self.inner.as_ref())
250    }
251
252    /// Returns a future that resolves after notification or mock timeout.
253    ///
254    /// # Arguments
255    ///
256    /// * `timeout` - Maximum mock duration to wait.
257    ///
258    /// # Returns
259    ///
260    /// A future resolving to the timeout status.
261    #[cfg(feature = "async")]
262    pub fn wait_for_async(&self, timeout: Duration) -> AsyncMonitorFuture<'_, WaitTimeoutStatus>
263    where
264        T: Send,
265    {
266        <MockMonitor<T> as AsyncTimeoutNotificationWaiter>::wait_for_async(
267            self.inner.as_ref(),
268            timeout,
269        )
270    }
271
272    /// Returns a future that waits until the predicate becomes true.
273    ///
274    /// # Arguments
275    ///
276    /// * `predicate` - Predicate that returns `true` when the state is ready.
277    /// * `action` - Action to run after the predicate becomes true.
278    ///
279    /// # Returns
280    ///
281    /// A future resolving to the action result.
282    #[cfg(feature = "async")]
283    pub fn wait_until_async<'a, R, P, F>(
284        &'a self,
285        predicate: P,
286        action: F,
287    ) -> AsyncMonitorFuture<'a, R>
288    where
289        T: Send,
290        R: Send + 'a,
291        P: FnMut(&T) -> bool + Send + 'a,
292        F: FnOnce(&mut T) -> R + Send + 'a,
293    {
294        <MockMonitor<T> as AsyncConditionWaiter>::wait_until_async(
295            self.inner.as_ref(),
296            predicate,
297            action,
298        )
299    }
300
301    /// Returns a future that waits while the predicate remains true.
302    ///
303    /// # Arguments
304    ///
305    /// * `predicate` - Predicate that returns `true` while waiting should continue.
306    /// * `action` - Action to run after the predicate becomes false.
307    ///
308    /// # Returns
309    ///
310    /// A future resolving to the action result.
311    #[cfg(feature = "async")]
312    pub fn wait_while_async<'a, R, P, F>(
313        &'a self,
314        predicate: P,
315        action: F,
316    ) -> AsyncMonitorFuture<'a, R>
317    where
318        T: Send,
319        R: Send + 'a,
320        P: FnMut(&T) -> bool + Send + 'a,
321        F: FnOnce(&mut T) -> R + Send + 'a,
322    {
323        <MockMonitor<T> as AsyncConditionWaiter>::wait_while_async(
324            self.inner.as_ref(),
325            predicate,
326            action,
327        )
328    }
329
330    /// Returns a future that waits until the predicate becomes true or times out.
331    ///
332    /// # Arguments
333    ///
334    /// * `timeout` - Maximum mock duration to wait.
335    /// * `predicate` - Predicate that returns `true` when the state is ready.
336    /// * `action` - Action to run after the predicate becomes true.
337    ///
338    /// # Returns
339    ///
340    /// A future resolving to the timed wait result.
341    #[cfg(feature = "async")]
342    pub fn wait_until_for_async<'a, R, P, F>(
343        &'a self,
344        timeout: Duration,
345        predicate: P,
346        action: F,
347    ) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
348    where
349        T: Send,
350        R: Send + 'a,
351        P: FnMut(&T) -> bool + Send + 'a,
352        F: FnOnce(&mut T) -> R + Send + 'a,
353    {
354        <MockMonitor<T> as AsyncTimeoutConditionWaiter>::wait_until_for_async(
355            self.inner.as_ref(),
356            timeout,
357            predicate,
358            action,
359        )
360    }
361
362    /// Returns a future that waits while the predicate remains true or times out.
363    ///
364    /// # Arguments
365    ///
366    /// * `timeout` - Maximum mock duration to wait.
367    /// * `predicate` - Predicate that returns `true` while waiting should continue.
368    /// * `action` - Action to run after the predicate becomes false.
369    ///
370    /// # Returns
371    ///
372    /// A future resolving to the timed wait result.
373    #[cfg(feature = "async")]
374    pub fn wait_while_for_async<'a, R, P, F>(
375        &'a self,
376        timeout: Duration,
377        predicate: P,
378        action: F,
379    ) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
380    where
381        T: Send,
382        R: Send + 'a,
383        P: FnMut(&T) -> bool + Send + 'a,
384        F: FnOnce(&mut T) -> R + Send + 'a,
385    {
386        <MockMonitor<T> as AsyncTimeoutConditionWaiter>::wait_while_for_async(
387            self.inner.as_ref(),
388            timeout,
389            predicate,
390            action,
391        )
392    }
393}
394
395impl<T> Notifier for ArcMockMonitor<T> {
396    /// Wakes one waiter.
397    fn notify_one(&self) {
398        Self::notify_one(self);
399    }
400
401    /// Wakes all waiters.
402    fn notify_all(&self) {
403        Self::notify_all(self);
404    }
405}
406
407impl<T> NotificationWaiter for ArcMockMonitor<T> {
408    /// Blocks until notification.
409    fn wait(&self) {
410        self.inner.wait();
411    }
412}
413
414impl<T> TimeoutNotificationWaiter for ArcMockMonitor<T> {
415    /// Blocks until notification or mock timeout.
416    fn wait_for(&self, timeout: Duration) -> WaitTimeoutStatus {
417        self.inner.wait_for(timeout)
418    }
419}
420
421impl<T> ConditionWaiter for ArcMockMonitor<T> {
422    type State = T;
423
424    /// Blocks while the predicate remains true, then runs the action.
425    fn wait_while<R, P, F>(&self, predicate: P, action: F) -> R
426    where
427        P: FnMut(&Self::State) -> bool,
428        F: FnOnce(&mut Self::State) -> R,
429    {
430        self.inner.wait_while(predicate, action)
431    }
432}
433
434impl<T> TimeoutConditionWaiter for ArcMockMonitor<T> {
435    /// Blocks while the predicate remains true or until mock timeout expires.
436    fn wait_while_for<R, P, F>(
437        &self,
438        timeout: Duration,
439        predicate: P,
440        action: F,
441    ) -> WaitTimeoutResult<R>
442    where
443        P: FnMut(&Self::State) -> bool,
444        F: FnOnce(&mut Self::State) -> R,
445    {
446        self.inner.wait_while_for(timeout, predicate, action)
447    }
448}
449
450#[cfg(feature = "async")]
451impl<T: Send> AsyncNotificationWaiter for ArcMockMonitor<T> {
452    /// Returns a future that resolves after an async notification.
453    fn wait_async<'a>(&'a self) -> AsyncMonitorFuture<'a, ()> {
454        self.inner.wait_async()
455    }
456}
457
458#[cfg(feature = "async")]
459impl<T: Send> AsyncTimeoutNotificationWaiter for ArcMockMonitor<T> {
460    /// Returns a future that resolves after notification or mock timeout.
461    fn wait_for_async<'a>(
462        &'a self,
463        timeout: Duration,
464    ) -> AsyncMonitorFuture<'a, WaitTimeoutStatus> {
465        self.inner.wait_for_async(timeout)
466    }
467}
468
469#[cfg(feature = "async")]
470impl<T: Send> AsyncConditionWaiter for ArcMockMonitor<T> {
471    type State = T;
472
473    /// Returns a future that waits while the predicate remains true.
474    fn wait_while_async<'a, R, P, F>(&'a self, predicate: P, action: F) -> AsyncMonitorFuture<'a, R>
475    where
476        R: Send + 'a,
477        P: FnMut(&Self::State) -> bool + Send + 'a,
478        F: FnOnce(&mut Self::State) -> R + Send + 'a,
479    {
480        self.inner.wait_while_async(predicate, action)
481    }
482}
483
484#[cfg(feature = "async")]
485impl<T: Send> AsyncTimeoutConditionWaiter for ArcMockMonitor<T> {
486    /// Returns a future that waits while the predicate remains true or times out.
487    fn wait_while_for_async<'a, R, P, F>(
488        &'a self,
489        timeout: Duration,
490        predicate: P,
491        action: F,
492    ) -> AsyncMonitorFuture<'a, WaitTimeoutResult<R>>
493    where
494        R: Send + 'a,
495        P: FnMut(&Self::State) -> bool + Send + 'a,
496        F: FnOnce(&mut Self::State) -> R + Send + 'a,
497    {
498        self.inner.wait_while_for_async(timeout, predicate, action)
499    }
500}
501
502impl<T> AsRef<MockMonitor<T>> for ArcMockMonitor<T> {
503    /// Returns a reference to the wrapped mock monitor.
504    fn as_ref(&self) -> &MockMonitor<T> {
505        self.inner.as_ref()
506    }
507}
508
509impl<T> Deref for ArcMockMonitor<T> {
510    type Target = MockMonitor<T>;
511
512    /// Dereferences to the wrapped mock monitor.
513    fn deref(&self) -> &Self::Target {
514        self.inner.as_ref()
515    }
516}
517
518impl<T> Clone for ArcMockMonitor<T> {
519    /// Clones this shared mock monitor handle.
520    fn clone(&self) -> Self {
521        Self {
522            inner: self.inner.clone(),
523        }
524    }
525}
526
527impl<T> From<T> for ArcMockMonitor<T> {
528    /// Creates an Arc-wrapped mock monitor from an initial state value.
529    fn from(value: T) -> Self {
530        Self::new(value)
531    }
532}
533
534impl<T: Default> Default for ArcMockMonitor<T> {
535    /// Creates an Arc-wrapped mock monitor containing `T::default()`.
536    fn default() -> Self {
537        Self::new(T::default())
538    }
539}