use crate::error::{NsbError, Result};
use crate::units::angular::Degrees;
pub(crate) const MAX_ZENITH_DEG: f64 = 90.0;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DirectPathGeometry {
zenith: Degrees,
}
impl DirectPathGeometry {
pub fn new(zenith: Degrees) -> Result<Self> {
let value = zenith.value();
if !value.is_finite() {
return Err(NsbError::OutOfRange(format!(
"direct-path zenith must be finite, got {value}"
)));
}
if !(0.0..=MAX_ZENITH_DEG).contains(&value) {
return Err(NsbError::OutOfRange(format!(
"direct-path zenith must be in [0, {MAX_ZENITH_DEG}] degrees, got {value}"
)));
}
Ok(Self { zenith })
}
pub const fn zenith(self) -> Degrees {
self.zenith
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn accepts_horizon_and_zenith() {
assert!(DirectPathGeometry::new(Degrees::new(0.0)).is_ok());
assert!(DirectPathGeometry::new(Degrees::new(90.0)).is_ok());
}
#[test]
fn rejects_nan_negative_and_above_horizon() {
assert!(DirectPathGeometry::new(Degrees::new(f64::NAN)).is_err());
assert!(DirectPathGeometry::new(Degrees::new(-0.1)).is_err());
assert!(DirectPathGeometry::new(Degrees::new(90.1)).is_err());
assert!(DirectPathGeometry::new(Degrees::new(f64::INFINITY)).is_err());
}
}