badi_date/badi_date/
mod.rs

1mod badi_month;
2pub use badi_month::BadiMonth;
3
4mod local_badi_date;
5pub use local_badi_date::*;
6
7mod badi_date_like;
8pub use badi_date_like::*;
9
10mod local_badi_date_like;
11pub use local_badi_date_like::*;
12
13mod coordinates;
14pub use coordinates::*;
15
16mod from_datetime;
17pub use from_datetime::*;
18
19mod badi_date_ops;
20pub use badi_date_ops::*;
21
22mod to_datetime;
23use serde::{Deserialize, Serialize};
24pub use to_datetime::*;
25
26mod util;
27
28use crate::{BadiDateError, HolyDayProviding};
29use util::*;
30
31use std::fmt;
32
33/// A structure that holds a date in the Badí‘ (Bahá’í) calendar without time zone or location info
34#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialOrd, PartialEq, Serialize)]
35pub struct BadiDate {
36    year: u8,
37    month: BadiMonth,
38    day: u16,
39    #[serde(skip)]
40    day_of_year: u16,
41}
42
43impl BadiDate {
44    /// Create a new [`BadiDate`] given day, [`BadiMonth`], and year; checks for validity
45    pub fn new(year: u8, month: BadiMonth, day: u16) -> Result<Self, BadiDateError> {
46        validate(year, month, day)?;
47        let day_of_year = day_of_year(year, &month, day);
48        Ok(Self {
49            year,
50            month,
51            day,
52            day_of_year,
53        })
54    }
55}
56
57impl BadiDateLike for BadiDate {
58    fn year(&self) -> u8 {
59        self.year
60    }
61
62    fn month(&self) -> BadiMonth {
63        self.month
64    }
65
66    fn day(&self) -> u16 {
67        self.day
68    }
69
70    fn day_of_year(&self) -> u16 {
71        self.day_of_year
72    }
73
74    fn with_day(&self, day: u16) -> Result<BadiDate, BadiDateError> {
75        Self::new(self.year, self.month, day)
76    }
77
78    fn with_month(&self, month: BadiMonth) -> Result<BadiDate, BadiDateError> {
79        Self::new(self.year, month, self.day)
80    }
81
82    fn with_year(&self, year: u8) -> Result<Self, BadiDateError> {
83        Self::new(year, self.month, self.day)
84    }
85
86    fn with_ymd(&self, year: u8, month: BadiMonth, day: u16) -> Result<BadiDate, BadiDateError> {
87        Self::new(year, month, day)
88    }
89
90    fn with_year_and_doy(&self, year: u8, day_of_year: u16) -> Result<Self, BadiDateError> {
91        let (month, day) = match month_and_day_from_doy(year, day_of_year) {
92            Ok(result) => result,
93            Err(err) => return Err(err),
94        };
95        Self::new(year, month, day)
96    }
97}
98
99impl HolyDayProviding for BadiDate {}
100
101impl fmt::Display for BadiDate {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        write!(
104            f,
105            "{:0>3}-{:0>2}-{:0>2}",
106            self.year,
107            match self.month {
108                BadiMonth::Month(month) => month,
109                BadiMonth::AyyamIHa => 0,
110            },
111            self.day,
112        )
113    }
114}