shaum_types/
error.rs

1//! Error types for Shaum.
2
3use chrono::NaiveDate;
4use serde::{Serialize, Deserialize};
5use std::fmt;
6
7/// Minimum Gregorian year for Hijri conversion.
8pub const HIJRI_MIN_YEAR: i32 = 1938;
9/// Maximum Gregorian year for Hijri conversion.
10pub const HIJRI_MAX_YEAR: i32 = 2076;
11
12/// Errors from shaum operations.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub enum ShaumError {
15    /// Date outside supported range (1938-2076).
16    DateOutOfRange {
17        date: NaiveDate,
18        min: NaiveDate,
19        max: NaiveDate,
20    },
21    
22    /// Invalid configuration.
23    InvalidConfiguration { reason: String },
24    
25    /// Analysis failure.
26    AnalysisError(String),
27
28    /// Hijri conversion error.
29    HijriConversionError(String),
30
31    /// Sunset calculation error.
32    SunsetCalculationError(String),
33
34    /// Moon provider error.
35    MoonProviderError(String),
36
37    /// Coordinate or input validation error.
38    ValidationError(String),
39
40    /// Astronomy calculation error (e.g., polar regions).
41    AstronomyError(String),
42
43    /// Database error (e.g., MaxMind GeoIP lookup).
44    DatabaseError(String),
45
46    /// Network error (async/remote operations).
47    NetworkError(String),
48}
49
50impl fmt::Display for ShaumError {
51    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52        match self {
53            Self::DateOutOfRange { date, min, max } => {
54                write!(f, "Date {} is out of supported range ({} to {})", date, min, max)
55            }
56            Self::InvalidConfiguration { reason } => write!(f, "Invalid configuration: {}", reason),
57            Self::AnalysisError(s) => write!(f, "Analysis failed: {}", s),
58            Self::HijriConversionError(s) => write!(f, "Hijri conversion failed: {}", s),
59            Self::SunsetCalculationError(s) => write!(f, "Sunset calculation failed: {}", s),
60            Self::MoonProviderError(s) => write!(f, "Moon provider error: {}", s),
61            Self::ValidationError(s) => write!(f, "Validation error: {}", s),
62            Self::AstronomyError(s) => write!(f, "Astronomy error: {}", s),
63            Self::DatabaseError(s) => write!(f, "Database error: {}", s),
64            Self::NetworkError(s) => write!(f, "Network error: {}", s),
65        }
66    }
67}
68
69impl std::error::Error for ShaumError {}
70
71impl ShaumError {
72    /// Creates a `DateOutOfRange` error with standard bounds.
73    pub fn date_out_of_range(date: NaiveDate) -> Self {
74        Self::DateOutOfRange {
75            date,
76            min: NaiveDate::from_ymd_opt(HIJRI_MIN_YEAR, 1, 1)
77                .unwrap_or_else(|| NaiveDate::from_ymd_opt(1938, 1, 1).unwrap()),
78            max: NaiveDate::from_ymd_opt(HIJRI_MAX_YEAR, 12, 31)
79                .unwrap_or_else(|| NaiveDate::from_ymd_opt(2076, 12, 31).unwrap()),
80        }
81    }
82    
83    /// Creates an `InvalidConfiguration` error.
84    pub fn invalid_config(reason: impl Into<String>) -> Self {
85        Self::InvalidConfiguration { reason: reason.into() }
86    }
87}