use std::time::Duration;
use qubit_clock::MonotonicInstant;
use qubit_clock::TimeError;
use thiserror::Error;
#[must_use]
#[derive(Debug, Error)]
pub enum TimeBudgetError<R> {
#[error("time budget for {resource:?} failed: {source}")]
Clock {
resource: R,
#[source]
source: TimeError,
},
#[error("time budget for {resource:?} expired at {deadline:?}; now is {now:?}")]
Expired {
resource: R,
deadline: MonotonicInstant,
now: MonotonicInstant,
},
#[error("time budget for {resource:?} at {now:?} cannot fit {requested:?} before {deadline:?}")]
WouldExpire {
resource: R,
deadline: MonotonicInstant,
now: MonotonicInstant,
requested: Duration,
},
}
impl<R> TimeBudgetError<R> {
#[must_use]
#[inline(always)]
pub const fn resource(&self) -> &R {
match self {
Self::Clock { resource, .. } | Self::Expired { resource, .. } | Self::WouldExpire { resource, .. } => {
resource
}
}
}
#[inline(always)]
#[must_use]
pub fn into_resource(self) -> R {
match self {
Self::Clock { resource, .. } | Self::Expired { resource, .. } | Self::WouldExpire { resource, .. } => {
resource
}
}
}
#[must_use]
#[inline(always)]
pub const fn clock_error(&self) -> Option<&TimeError> {
match self {
Self::Clock { source, .. } => Some(source),
Self::Expired { .. } | Self::WouldExpire { .. } => None,
}
}
#[must_use]
#[inline(always)]
pub const fn deadline(&self) -> Option<MonotonicInstant> {
match self {
Self::Expired { deadline, .. } | Self::WouldExpire { deadline, .. } => Some(*deadline),
Self::Clock { .. } => None,
}
}
#[must_use]
#[inline(always)]
pub const fn now(&self) -> Option<MonotonicInstant> {
match self {
Self::Expired { now, .. } | Self::WouldExpire { now, .. } => Some(*now),
Self::Clock { .. } => None,
}
}
#[must_use]
#[inline(always)]
pub const fn requested(&self) -> Option<Duration> {
match self {
Self::WouldExpire { requested, .. } => Some(*requested),
Self::Clock { .. } | Self::Expired { .. } => None,
}
}
}