use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum WesternZodiac {
Aries,
Taurus,
Gemini,
Cancer,
Leo,
Virgo,
Libra,
Scorpio,
Sagittarius,
Capricorn,
Aquarius,
Pisces,
}
pub const fn western_zodiac(solar_month: u8, solar_day: u8) -> Option<WesternZodiac> {
let sign = match (solar_month, solar_day) {
(3, 21..=31) | (4, 1..=19) => WesternZodiac::Aries,
(4, 20..=30) | (5, 1..=20) => WesternZodiac::Taurus,
(5, 21..=31) | (6, 1..=21) => WesternZodiac::Gemini,
(6, 22..=30) | (7, 1..=22) => WesternZodiac::Cancer,
(7, 23..=31) | (8, 1..=22) => WesternZodiac::Leo,
(8, 23..=31) | (9, 1..=22) => WesternZodiac::Virgo,
(9, 23..=30) | (10, 1..=23) => WesternZodiac::Libra,
(10, 24..=31) | (11, 1..=22) => WesternZodiac::Scorpio,
(11, 23..=30) | (12, 1..=21) => WesternZodiac::Sagittarius,
(12, 22..=31) | (1, 1..=19) => WesternZodiac::Capricorn,
(1, 20..=31) | (2, 1..=18) => WesternZodiac::Aquarius,
(2, 19..=29) | (3, 1..=20) => WesternZodiac::Pisces,
_ => return None,
};
Some(sign)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn boundary_dates_map_to_expected_signs() {
assert_eq!(western_zodiac(5, 27), Some(WesternZodiac::Gemini));
assert_eq!(western_zodiac(5, 20), Some(WesternZodiac::Taurus));
assert_eq!(western_zodiac(5, 21), Some(WesternZodiac::Gemini));
assert_eq!(western_zodiac(1, 1), Some(WesternZodiac::Capricorn));
assert_eq!(western_zodiac(12, 25), Some(WesternZodiac::Capricorn));
}
#[test]
fn invalid_dates_return_none() {
assert_eq!(western_zodiac(0, 1), None);
assert_eq!(western_zodiac(13, 1), None);
assert_eq!(western_zodiac(2, 30), None);
}
}