shaum_types/
geo.rs

1//! Geographic and visibility types.
2
3use serde::{Serialize, Deserialize};
4
5/// Geographic coordinates (Latitude, Longitude) with optional Altitude.
6#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
7pub struct GeoCoordinate {
8    pub lat: f64,
9    pub lng: f64,
10    /// Altitude above sea level in meters. Default: 0.0
11    pub altitude: f64,
12}
13
14impl GeoCoordinate {
15    /// Creates a new validated coordinate (altitude defaults to 0).
16    ///
17    /// Returns `Err(ShaumError::ValidationError)` if coordinates are out of range.
18    pub fn new(lat: f64, lng: f64) -> Result<Self, crate::ShaumError> {
19        if !(-90.0..=90.0).contains(&lat) {
20            return Err(crate::ShaumError::ValidationError(
21                format!("Latitude {} out of range [-90, 90]", lat)
22            ));
23        }
24        if !(-180.0..=180.0).contains(&lng) {
25            return Err(crate::ShaumError::ValidationError(
26                format!("Longitude {} out of range [-180, 180]", lng)
27            ));
28        }
29        Ok(Self { lat, lng, altitude: 0.0 })
30    }
31
32    /// Creates a coordinate without validation. Use with trusted inputs only.
33    #[inline]
34    pub const fn new_unchecked(lat: f64, lng: f64) -> Self {
35        Self { lat, lng, altitude: 0.0 }
36    }
37    
38    /// Sets the altitude (meters above sea level).
39    pub fn with_altitude(mut self, altitude: f64) -> Self {
40        self.altitude = altitude;
41        self
42    }
43}
44
45/// Configurable moon visibility criteria for hilal observation.
46///
47/// Controls the thresholds used when determining if the crescent moon
48/// is visible. Default values match MABIMS (Indonesia/Malaysia/Brunei/Singapore).
49#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
50pub struct VisibilityCriteria {
51    /// Minimum moon altitude above horizon (degrees). Default: 3.0
52    pub min_altitude: f64,
53    /// Minimum elongation between sun and moon (degrees). Default: 6.4
54    pub min_elongation: f64,
55}
56
57impl Default for VisibilityCriteria {
58    fn default() -> Self {
59        Self { min_altitude: 3.0, min_elongation: 6.4 }
60    }
61}
62
63impl VisibilityCriteria {
64    /// Creates new visibility criteria with custom thresholds.
65    pub fn new(min_altitude: f64, min_elongation: f64) -> Self {
66        Self { min_altitude, min_elongation }
67    }
68
69    /// MABIMS criteria (default for Southeast Asia).
70    pub fn mabims() -> Self { Self::default() }
71
72    /// Istanbul 1978 criteria (more conservative).
73    pub fn istanbul_1978() -> Self {
74        Self { min_altitude: 5.0, min_elongation: 8.0 }
75    }
76}