use super::common_validators::ValidatorFn;
use crate::error::ValidationError;
use crate::value::Value;
pub struct MinIntValidator(pub i64);
impl ValidatorFn for MinIntValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(n) = value.coerce_to_int()
&& n < self.0
{
return Err(ValidationError::new(
field,
format!("minimum value is {}, got {n}", self.0),
"min",
));
}
Ok(())
}
}
pub struct MaxIntValidator(pub i64);
impl ValidatorFn for MaxIntValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(n) = value.coerce_to_int()
&& n > self.0
{
return Err(ValidationError::new(
field,
format!("maximum value is {}, got {n}", self.0),
"max",
));
}
Ok(())
}
}
pub struct MinFloatValidator(pub f64);
impl ValidatorFn for MinFloatValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(f) = value.coerce_to_float()
&& f < self.0
{
return Err(ValidationError::new(
field,
format!("minimum value is {}, got {f}", self.0),
"min",
));
}
Ok(())
}
}
pub struct MaxFloatValidator(pub f64);
impl ValidatorFn for MaxFloatValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(f) = value.coerce_to_float()
&& f > self.0
{
return Err(ValidationError::new(
field,
format!("maximum value is {}, got {f}", self.0),
"max",
));
}
Ok(())
}
}
pub struct PositiveValidator;
impl ValidatorFn for PositiveValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(f) = value.coerce_to_float()
&& f <= 0.0
{
return Err(ValidationError::new(
field,
"value must be positive",
"positive",
));
}
Ok(())
}
}
pub struct NegativeValidator;
impl ValidatorFn for NegativeValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(f) = value.coerce_to_float()
&& f >= 0.0
{
return Err(ValidationError::new(
field,
"value must be negative",
"negative",
));
}
Ok(())
}
}
pub struct NonZeroValidator;
impl ValidatorFn for NonZeroValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(f) = value.coerce_to_float()
&& f == 0.0
{
return Err(ValidationError::new(
field,
"value must not be zero",
"non_zero",
));
}
Ok(())
}
}
pub struct RangeValidator {
pub min: f64,
pub max: f64,
}
impl ValidatorFn for RangeValidator {
fn validate(&self, value: &Value, field: &str) -> Result<(), ValidationError> {
if let Some(f) = value.coerce_to_float()
&& (f < self.min || f > self.max)
{
return Err(ValidationError::new(
field,
format!(
"value must be in range [{}, {}], got {f}",
self.min, self.max
),
"range",
));
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_min_int_pass() {
assert!(MinIntValidator(5).validate(&Value::Int(10), "n").is_ok());
}
#[test]
fn test_min_int_fail() {
assert!(MinIntValidator(5).validate(&Value::Int(3), "n").is_err());
}
#[test]
fn test_max_int_pass() {
assert!(MaxIntValidator(100).validate(&Value::Int(50), "n").is_ok());
}
#[test]
fn test_max_int_fail() {
assert!(
MaxIntValidator(100)
.validate(&Value::Int(200), "n")
.is_err()
);
}
#[test]
fn test_min_float_fail() {
assert!(
MinFloatValidator(1.0)
.validate(&Value::Float(0.5), "f")
.is_err()
);
}
#[test]
fn test_max_float_fail() {
assert!(
MaxFloatValidator(1.0)
.validate(&Value::Float(1.5), "f")
.is_err()
);
}
#[test]
fn test_positive_fail_zero() {
assert!(PositiveValidator.validate(&Value::Int(0), "n").is_err());
}
#[test]
fn test_positive_pass() {
assert!(PositiveValidator.validate(&Value::Int(1), "n").is_ok());
}
#[test]
fn test_negative_fail() {
assert!(NegativeValidator.validate(&Value::Int(1), "n").is_err());
}
#[test]
fn test_non_zero_fail() {
assert!(NonZeroValidator.validate(&Value::Int(0), "n").is_err());
}
#[test]
fn test_non_zero_pass() {
assert!(NonZeroValidator.validate(&Value::Int(5), "n").is_ok());
}
#[test]
fn test_range_pass() {
assert!(
RangeValidator {
min: 0.0,
max: 100.0
}
.validate(&Value::Int(50), "n")
.is_ok()
);
}
#[test]
fn test_range_fail() {
assert!(
RangeValidator {
min: 0.0,
max: 10.0
}
.validate(&Value::Int(11), "n")
.is_err()
);
}
}