use std::fmt::Debug;
use std::fmt::Display;
use std::ops::Add;
use std::ops::Sub;
use super::internal::ResourceQuantitySealed;
use crate::resource::QuantityConversionError;
use crate::resource::QuantityMeasurement;
pub trait ResourceQuantity:
ResourceQuantitySealed + Copy + Debug + Display + Eq + Ord + Add<Output = Self> + Sub<Output = Self>
{
const ZERO: Self;
const ONE: Self;
#[must_use]
fn checked_add(self, other: Self) -> Option<Self>;
fn try_from_usize(value: usize) -> Result<Self, QuantityConversionError>;
fn try_from_u64(value: u64) -> Result<Self, QuantityConversionError>;
}
macro_rules! impl_resource_quantity {
($($quantity:ty),+ $(,)?) => {
$(
impl ResourceQuantitySealed for $quantity {}
impl ResourceQuantity for $quantity {
const ZERO: Self = 0;
const ONE: Self = 1;
#[inline]
fn checked_add(self, other: Self) -> Option<Self> {
Self::checked_add(self, other)
}
#[inline]
fn try_from_usize(value: usize) -> Result<Self, QuantityConversionError> {
<$quantity>::try_from(value).map_err(|_| {
QuantityConversionError::new(
QuantityMeasurement::Usize(value),
stringify!($quantity),
)
})
}
#[inline]
fn try_from_u64(value: u64) -> Result<Self, QuantityConversionError> {
<$quantity>::try_from(value).map_err(|_| {
QuantityConversionError::new(
QuantityMeasurement::U64(value),
stringify!($quantity),
)
})
}
}
)+
};
}
impl_resource_quantity!(u8, u16, u32, u64, u128, usize);