Skip to main content

qubit_lock/monitor/
wait_timeout_result.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//! # Wait Timeout Result
11//!
12//! Provides the result returned by predicate-based timed monitor waits.
13//!
14
15/// Result of waiting for a predicate with an overall timeout.
16///
17/// This type is returned by
18/// [`ParkingLotMonitor::wait_while_for`](super::ParkingLotMonitor::wait_while_for) and
19/// [`ParkingLotMonitor::wait_until_for`](super::ParkingLotMonitor::wait_until_for). It is
20/// more explicit than `Option<R>`: a ready predicate produces [`Self::Ready`],
21/// while an expired timeout produces [`Self::TimedOut`].
22///
23/// # Type Parameters
24///
25/// * `R` - The value produced after the protected state satisfies the
26///   predicate.
27///
28/// # Example
29///
30/// ```rust
31/// use std::time::Duration;
32///
33/// use qubit_lock::{ParkingLotMonitor, WaitTimeoutResult};
34///
35/// let monitor = ParkingLotMonitor::new(true);
36/// let result = monitor.wait_until_for(
37///     Duration::from_secs(1),
38///     |ready| *ready,
39///     |ready| {
40///         *ready = false;
41///         "ready"
42///     },
43/// );
44///
45/// assert_eq!(result, WaitTimeoutResult::Ready("ready"));
46/// ```
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum WaitTimeoutResult<R> {
49    /// The predicate became ready before the timeout and produced this value.
50    Ready(R),
51    /// The timeout elapsed before the predicate became ready.
52    TimedOut,
53}
54
55impl<R> WaitTimeoutResult<R> {
56    /// Returns `true` when the result contains a ready value.
57    ///
58    /// # Returns
59    ///
60    /// `true` for [`Self::Ready`], otherwise `false`.
61    #[inline]
62    pub const fn is_ready(&self) -> bool {
63        match self {
64            Self::Ready(_) => true,
65            Self::TimedOut => false,
66        }
67    }
68
69    /// Returns `true` when the timeout elapsed before the predicate was ready.
70    ///
71    /// # Returns
72    ///
73    /// `true` for [`Self::TimedOut`], otherwise `false`.
74    #[inline]
75    pub const fn is_timed_out(&self) -> bool {
76        match self {
77            Self::Ready(_) => false,
78            Self::TimedOut => true,
79        }
80    }
81
82    /// Converts this result into an [`Option`].
83    ///
84    /// # Returns
85    ///
86    /// `Some(value)` for [`Self::Ready`], or `None` for [`Self::TimedOut`].
87    #[inline]
88    pub fn into_option(self) -> Option<R> {
89        match self {
90            Self::Ready(value) => Some(value),
91            Self::TimedOut => None,
92        }
93    }
94
95    /// Maps a ready value while preserving timeout status.
96    ///
97    /// # Arguments
98    ///
99    /// * `f` - Closure applied to the contained value when this result is
100    ///   [`Self::Ready`].
101    ///
102    /// # Returns
103    ///
104    /// [`Self::Ready`] containing the mapped value, or
105    /// [`WaitTimeoutResult::TimedOut`] when this result timed out.
106    #[inline]
107    pub fn map<U, F: FnOnce(R) -> U>(self, f: F) -> WaitTimeoutResult<U> {
108        match self {
109            Self::Ready(value) => WaitTimeoutResult::Ready(f(value)),
110            Self::TimedOut => WaitTimeoutResult::TimedOut,
111        }
112    }
113}