use std::time::Duration;
use crate::argument::{
ArgumentError,
ArgumentErrorKind,
ArgumentResult,
ArgumentValue,
ComparisonConstraint,
sealed::Sealed,
};
pub trait DurationArgument: Sealed + Sized {
fn require_positive(self, path: &str) -> ArgumentResult<Self>;
fn require_less_than(self, path: &str, bound: Self)
-> ArgumentResult<Self>;
fn require_at_most(self, path: &str, bound: Self) -> ArgumentResult<Self>;
fn require_greater_than(
self,
path: &str,
bound: Self,
) -> ArgumentResult<Self>;
fn require_at_least(self, path: &str, bound: Self) -> ArgumentResult<Self>;
}
impl DurationArgument for Duration {
#[inline]
fn require_positive(self, path: &str) -> ArgumentResult<Self> {
validate_duration_comparison(
self,
path,
Duration::ZERO,
ComparisonConstraint::GreaterThan(ArgumentValue::from(
Duration::ZERO,
)),
|actual, bound| actual > bound,
)
}
#[inline]
fn require_less_than(
self,
path: &str,
bound: Self,
) -> ArgumentResult<Self> {
validate_duration_comparison(
self,
path,
bound,
ComparisonConstraint::LessThan(ArgumentValue::from(bound)),
|actual, bound| actual < bound,
)
}
#[inline]
fn require_at_most(self, path: &str, bound: Self) -> ArgumentResult<Self> {
validate_duration_comparison(
self,
path,
bound,
ComparisonConstraint::AtMost(ArgumentValue::from(bound)),
|actual, bound| actual <= bound,
)
}
#[inline]
fn require_greater_than(
self,
path: &str,
bound: Self,
) -> ArgumentResult<Self> {
validate_duration_comparison(
self,
path,
bound,
ComparisonConstraint::GreaterThan(ArgumentValue::from(bound)),
|actual, bound| actual > bound,
)
}
#[inline]
fn require_at_least(self, path: &str, bound: Self) -> ArgumentResult<Self> {
validate_duration_comparison(
self,
path,
bound,
ComparisonConstraint::AtLeast(ArgumentValue::from(bound)),
|actual, bound| actual >= bound,
)
}
}
fn validate_duration_comparison<F>(
actual: Duration,
path: &str,
bound: Duration,
constraint: ComparisonConstraint,
predicate: F,
) -> ArgumentResult<Duration>
where
F: FnOnce(Duration, Duration) -> bool,
{
if predicate(actual, bound) {
Ok(actual)
} else {
Err(ArgumentError::new(
path,
ArgumentErrorKind::Comparison {
actual: ArgumentValue::from(actual),
constraint,
},
))
}
}