use crate::core::error::ChartError;
use lunar_lite::EarthlyBranch;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct LunarMonth(u8);
impl LunarMonth {
pub const fn new(value: u8) -> Result<Self, ChartError> {
if value == 0 || value > 12 {
return Err(ChartError::InvalidLunarMonth { value });
}
Ok(Self(value))
}
pub const fn value(self) -> u8 {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct LunarDay(u8);
impl LunarDay {
pub const fn new(value: u8) -> Result<Self, ChartError> {
if value == 0 || value > 30 {
return Err(ChartError::InvalidLunarDay { value });
}
Ok(Self(value))
}
pub const fn value(self) -> u8 {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct LunarBirthContext {
lunar_month: LunarMonth,
birth_time: EarthlyBranch,
}
impl LunarBirthContext {
pub const fn new(lunar_month: LunarMonth, birth_time: EarthlyBranch) -> Self {
Self {
lunar_month,
birth_time,
}
}
pub const fn lunar_month(self) -> LunarMonth {
self.lunar_month
}
pub const fn birth_time(self) -> EarthlyBranch {
self.birth_time
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct LifeBodyPalaceIndices {
life_palace_branch: EarthlyBranch,
body_palace_branch: EarthlyBranch,
}
impl LifeBodyPalaceIndices {
pub const fn new(life_palace_branch: EarthlyBranch, body_palace_branch: EarthlyBranch) -> Self {
Self {
life_palace_branch,
body_palace_branch,
}
}
pub const fn life_palace_branch(self) -> EarthlyBranch {
self.life_palace_branch
}
pub const fn body_palace_branch(self) -> EarthlyBranch {
self.body_palace_branch
}
}
pub fn calculate_life_body_palace_indices(
context: LunarBirthContext,
) -> Result<LifeBodyPalaceIndices, ChartError> {
let month_offset = isize::from(context.lunar_month().value() - 1);
let hour_offset = context.birth_time().index() as isize - EarthlyBranch::Zi.index() as isize;
let month_anchor = EarthlyBranch::Yin.offset(month_offset);
Ok(LifeBodyPalaceIndices::new(
month_anchor.offset(-hour_offset),
month_anchor.offset(hour_offset),
))
}