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/// [`Monitor::wait_timeout_while`](super::Monitor::wait_timeout_while) and
19/// [`Monitor::wait_timeout_until`](super::Monitor::wait_timeout_until). 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::{Monitor, WaitTimeoutResult};
34///
35/// let monitor = Monitor::new(true);
36/// let result = monitor.wait_timeout_until(
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}