use super::error::{
ArgumentError,
ArgumentResult,
};
use std::fmt::Display;
pub trait NumericArgument: Sized {
fn require_zero(self, name: &str) -> ArgumentResult<Self>;
fn require_non_zero(self, name: &str) -> ArgumentResult<Self>;
fn require_positive(self, name: &str) -> ArgumentResult<Self>;
fn require_non_negative(self, name: &str) -> ArgumentResult<Self>;
fn require_negative(self, name: &str) -> ArgumentResult<Self>;
fn require_non_positive(self, name: &str) -> ArgumentResult<Self>;
fn require_in_closed_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self>;
fn require_in_open_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self>;
fn require_in_left_open_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self>;
fn require_in_right_open_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self>;
fn require_less(self, name: &str, max: Self) -> ArgumentResult<Self>;
fn require_less_equal(self, name: &str, max: Self) -> ArgumentResult<Self>;
fn require_greater(self, name: &str, min: Self) -> ArgumentResult<Self>;
fn require_greater_equal(self, name: &str, min: Self) -> ArgumentResult<Self>;
}
impl<T> NumericArgument for T
where
T: PartialOrd + Default + Display + Copy,
{
#[inline]
fn require_zero(self, name: &str) -> ArgumentResult<Self> {
if self != T::default() {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be zero but was: {}",
name, self
)));
}
Ok(self)
}
#[inline]
fn require_non_zero(self, name: &str) -> ArgumentResult<Self> {
if self == T::default() {
return Err(ArgumentError::new(format!(
"Parameter '{}' cannot be zero",
name
)));
}
Ok(self)
}
#[inline]
fn require_positive(self, name: &str) -> ArgumentResult<Self> {
if self <= T::default() {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be positive but was: {}",
name, self
)));
}
Ok(self)
}
#[inline]
fn require_non_negative(self, name: &str) -> ArgumentResult<Self> {
if self < T::default() {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be non-negative but was: {}",
name, self
)));
}
Ok(self)
}
#[inline]
fn require_negative(self, name: &str) -> ArgumentResult<Self> {
if self >= T::default() {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be negative but was: {}",
name, self
)));
}
Ok(self)
}
#[inline]
fn require_non_positive(self, name: &str) -> ArgumentResult<Self> {
if self > T::default() {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be non-positive but was: {}",
name, self
)));
}
Ok(self)
}
#[inline]
fn require_in_closed_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self> {
if self < min || self > max {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be in range [{}, {}] but was: {}",
name, min, max, self
)));
}
Ok(self)
}
#[inline]
fn require_in_open_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self> {
if self <= min || self >= max {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be in range ({}, {}) but was: {}",
name, min, max, self
)));
}
Ok(self)
}
#[inline]
fn require_in_left_open_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self> {
if self <= min || self > max {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be in range ({}, {}] but was: {}",
name, min, max, self
)));
}
Ok(self)
}
#[inline]
fn require_in_right_open_range(self, name: &str, min: Self, max: Self) -> ArgumentResult<Self> {
if self < min || self >= max {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be in range [{}, {}) but was: {}",
name, min, max, self
)));
}
Ok(self)
}
#[inline]
fn require_less(self, name: &str, max: Self) -> ArgumentResult<Self> {
if self >= max {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be less than {} but was: {}",
name, max, self
)));
}
Ok(self)
}
#[inline]
fn require_less_equal(self, name: &str, max: Self) -> ArgumentResult<Self> {
if self > max {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be less than or equal to {} but was: {}",
name, max, self
)));
}
Ok(self)
}
#[inline]
fn require_greater(self, name: &str, min: Self) -> ArgumentResult<Self> {
if self <= min {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be greater than {} but was: {}",
name, min, self
)));
}
Ok(self)
}
#[inline]
fn require_greater_equal(self, name: &str, min: Self) -> ArgumentResult<Self> {
if self < min {
return Err(ArgumentError::new(format!(
"Parameter '{}' must be greater than or equal to {} but was: {}",
name, min, self
)));
}
Ok(self)
}
}
#[inline]
pub fn require_equal<T>(name1: &str, value1: T, name2: &str, value2: T) -> ArgumentResult<()>
where
T: PartialEq + Display,
{
if value1 != value2 {
return Err(ArgumentError::new(format!(
"Parameter '{}' ({}) must equal parameter '{}' ({})",
name1, value1, name2, value2
)));
}
Ok(())
}
#[inline]
pub fn require_not_equal<T>(name1: &str, value1: T, name2: &str, value2: T) -> ArgumentResult<()>
where
T: PartialEq + Display,
{
if value1 == value2 {
return Err(ArgumentError::new(format!(
"Parameters '{}' and '{}' cannot be equal (both are: {})",
name1, name2, value1
)));
}
Ok(())
}