#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct EnvVarValidationResult {
pub effective: i32,
pub status: ValidationStatus,
pub message: Option<String>,
}
#[derive(Debug, Clone)]
pub enum ValidationStatus {
Valid,
Capped,
Invalid,
}
pub fn validate_bounded_int_env_var(
name: &str,
value: Option<&str>,
default_value: i32,
upper_limit: i32,
) -> EnvVarValidationResult {
let value = match value {
Some(v) => v,
None => {
return EnvVarValidationResult {
effective: default_value,
status: ValidationStatus::Valid,
message: None,
}
}
};
let parsed = match value.parse::<i32>() {
Ok(p) => p,
Err(_) => {
return EnvVarValidationResult {
effective: default_value,
status: ValidationStatus::Invalid,
message: Some(format!(
"Invalid value \"{}\" (using default: {})",
value, default_value
)),
}
}
};
if parsed <= 0 {
return EnvVarValidationResult {
effective: default_value,
status: ValidationStatus::Invalid,
message: Some(format!(
"Invalid value \"{}\" (using default: {})",
value, default_value
)),
};
}
if parsed > upper_limit {
return EnvVarValidationResult {
effective: upper_limit,
status: ValidationStatus::Capped,
message: Some(format!("Capped from {} to {}", parsed, upper_limit)),
};
}
EnvVarValidationResult {
effective: parsed,
status: ValidationStatus::Valid,
message: None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_bounded_int_env_var_default() {
let result = validate_bounded_int_env_var("TEST", None, 10, 100);
assert_eq!(result.effective, 10);
assert!(matches!(result.status, ValidationStatus::Valid));
}
#[test]
fn test_validate_bounded_int_env_var_capped() {
let result = validate_bounded_int_env_var("TEST", Some("200"), 10, 100);
assert_eq!(result.effective, 100);
assert!(matches!(result.status, ValidationStatus::Capped));
}
#[test]
fn test_validate_bounded_int_env_var_invalid() {
let result = validate_bounded_int_env_var("TEST", Some("abc"), 10, 100);
assert_eq!(result.effective, 10);
assert!(matches!(result.status, ValidationStatus::Invalid));
}
}