use crate::error::StaticError;
pub fn validate_fraction(what: &str, x: f64) -> Result<(), StaticError> {
if x.is_finite() && (0.0..=1.0).contains(&x) {
Ok(())
} else {
Err(StaticError::InvalidInput(format!(
"{what} must be a fraction in [0,1], got {x}"
)))
}
}
pub fn validate_positive(what: &str, x: f64) -> Result<(), StaticError> {
if x.is_finite() && x > 0.0 {
Ok(())
} else {
Err(StaticError::InvalidInput(format!(
"{what} must be finite and > 0, got {x}"
)))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fraction_accepts_unit_interval_endpoints() {
assert!(validate_fraction("phi", 0.0).is_ok());
assert!(validate_fraction("phi", 1.0).is_ok());
assert!(validate_fraction("phi", 0.25).is_ok());
}
#[test]
fn fraction_rejects_the_h2_garbage_cases() {
assert!(validate_fraction("porosity", -0.1).is_err()); assert!(validate_fraction("water_saturation", 1.2).is_err()); assert!(validate_fraction("net_to_gross", f64::NAN).is_err());
assert!(validate_fraction("porosity", f64::INFINITY).is_err());
}
#[test]
fn positive_rejects_zero_negative_and_nonfinite() {
assert!(validate_positive("area", 100.0).is_ok());
assert!(validate_positive("area", 0.0).is_err());
assert!(validate_positive("gross_height", -5.0).is_err());
assert!(validate_positive("area", f64::INFINITY).is_err());
}
}