use std::error::Error;
use std::fmt;
use std::sync::mpsc::{Receiver, RecvTimeoutError};
use std::time::Duration;
const MAX_TEST_TIMEOUT: Duration = Duration::from_secs(30);
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct BoundedTimeout(Duration);
impl BoundedTimeout {
pub fn new(duration: Duration) -> Result<Self, BoundedTimeoutError> {
if duration.is_zero() {
return Err(BoundedTimeoutError::Zero);
}
if duration > MAX_TEST_TIMEOUT {
return Err(BoundedTimeoutError::ExceedsMaximum {
maximum: MAX_TEST_TIMEOUT,
});
}
Ok(Self(duration))
}
#[must_use]
pub const fn duration(self) -> Duration {
self.0
}
pub fn receive<T>(self, receiver: &Receiver<T>) -> Result<T, RecvTimeoutError> {
receiver.recv_timeout(self.0)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum BoundedTimeoutError {
Zero,
ExceedsMaximum {
maximum: Duration,
},
}
impl fmt::Display for BoundedTimeoutError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Zero => formatter.write_str("bounded test timeout must be nonzero"),
Self::ExceedsMaximum { maximum } => {
write!(formatter, "bounded test timeout exceeds {maximum:?}")
}
}
}
}
impl Error for BoundedTimeoutError {}