use std::fmt::Debug;
use thiserror::Error;
use crate::resource::BudgetError;
use crate::resource::InsufficientBudgetError;
use crate::resource::LimitExceededError;
use crate::resource::QuantityConversionError;
#[derive(Clone, Debug, Error)]
pub enum MeasuredBudgetError<R, Q = u64>
where
Q: Copy + Debug,
{
#[error("resource {resource:?} has an unrepresentable measurement: {source}")]
Quantity {
resource: R,
#[source]
source: QuantityConversionError,
},
#[error(transparent)]
Budget(#[from] BudgetError<R, Q>),
}
impl<R, Q> MeasuredBudgetError<R, Q>
where
Q: Copy + Debug,
{
#[inline(always)]
#[must_use]
pub const fn quantity(resource: R, source: QuantityConversionError) -> Self {
Self::Quantity { resource, source }
}
#[must_use]
#[inline(always)]
pub const fn budget_error(&self) -> Option<&BudgetError<R, Q>> {
match self {
Self::Budget(error) => Some(error),
Self::Quantity { .. } => None,
}
}
#[must_use]
#[inline(always)]
pub const fn quantity_error(&self) -> Option<&QuantityConversionError> {
match self {
Self::Quantity { source, .. } => Some(source),
Self::Budget(_) => None,
}
}
#[must_use]
#[inline(always)]
pub const fn resource(&self) -> &R {
match self {
Self::Quantity { resource, .. } => resource,
Self::Budget(error) => error.resource(),
}
}
#[inline(always)]
#[must_use]
pub fn into_resource(self) -> R {
match self {
Self::Quantity { resource, .. } => resource,
Self::Budget(error) => error.into_resource(),
}
}
}
impl<R, Q> From<LimitExceededError<R, Q>> for MeasuredBudgetError<R, Q>
where
Q: Copy + Debug,
{
#[inline(always)]
fn from(error: LimitExceededError<R, Q>) -> Self {
Self::Budget(error.into())
}
}
impl<R, Q> From<InsufficientBudgetError<R, Q>> for MeasuredBudgetError<R, Q>
where
Q: Copy + Debug,
{
#[inline(always)]
fn from(error: InsufficientBudgetError<R, Q>) -> Self {
Self::Budget(error.into())
}
}