temporal_core 0.0.1

An Intl-first date time library
Documentation
use std::str::FromStr;

use crate::{duration::NominalDuration, iso::IsoDate};

#[derive(Debug, Clone, Copy)]
pub enum Calendar {
    Iso8601,
    Persian,
}

impl FromStr for Calendar {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match s {
            "iso8601" => Self::Iso8601,
            "persian" => Self::Persian,
            _ => return Err(()),
        })
    }
}

pub struct Era {
    pub name: String,
    pub year: u32,
}

pub enum FromYMDResult {
    Normal(IsoDate),
    OverflowConstrained(IsoDate),
}

pub trait CalendarProtocol {
    fn id(&self) -> String;
    fn era(&self, iso_date: IsoDate) -> Option<Era>;
    fn year(&self, iso_date: IsoDate) -> i32;
    fn month(&self, iso_date: IsoDate) -> u32;
    fn month_code(&self, iso_date: IsoDate) -> String;
    fn day(&self, iso_date: IsoDate) -> u32;
    fn day_of_week(&self, iso_date: IsoDate) -> u32;
    fn day_of_year(&self, iso_date: IsoDate) -> u32;
    fn week_of_year(&self, iso_date: IsoDate) -> u32;
    fn days_in_week(&self, iso_date: IsoDate) -> u32;
    fn days_in_month(&self, iso_date: IsoDate) -> u32;
    fn days_in_year(&self, iso_date: IsoDate) -> u32;
    fn months_in_year(&self, iso_date: IsoDate) -> u32;
    fn in_leap_year(&self, iso_date: IsoDate) -> bool;
    fn from_ymd(&self, year: i32, month: u32, day: u32) -> FromYMDResult;
    fn date_add(&self, iso_date: IsoDate, dur: NominalDuration) -> FromYMDResult;
}

pub(crate) struct IsoCalendar;

mod impls;

impl Calendar {
    fn to_trait_obj(self) -> Box<dyn CalendarProtocol> {
        match self {
            Calendar::Iso8601 => Box::new(IsoCalendar),
            Calendar::Persian => todo!(),
        }
    }
}

#[allow(unused_variables)]
impl CalendarProtocol for Calendar {
    fn id(&self) -> String {
        self.to_trait_obj().id()
    }

    fn era(&self, iso_date: IsoDate) -> Option<Era> {
        self.to_trait_obj().era(iso_date)
    }

    fn year(&self, iso_date: IsoDate) -> i32 {
        self.to_trait_obj().year(iso_date)
    }

    fn month(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().month(iso_date)
    }

    fn month_code(&self, iso_date: IsoDate) -> String {
        self.to_trait_obj().month_code(iso_date)
    }

    fn day(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().day(iso_date)
    }

    fn day_of_week(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().day_of_week(iso_date)
    }

    fn day_of_year(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().day_of_year(iso_date)
    }

    fn week_of_year(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().week_of_year(iso_date)
    }

    fn days_in_week(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().days_in_week(iso_date)
    }

    fn days_in_month(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().days_in_month(iso_date)
    }

    fn days_in_year(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().days_in_year(iso_date)
    }

    fn months_in_year(&self, iso_date: IsoDate) -> u32 {
        self.to_trait_obj().months_in_year(iso_date)
    }

    fn in_leap_year(&self, iso_date: IsoDate) -> bool {
        self.to_trait_obj().in_leap_year(iso_date)
    }

    fn from_ymd(&self, year: i32, month: u32, day: u32) -> FromYMDResult {
        self.to_trait_obj().from_ymd(year, month, day)
    }

    fn date_add(&self, iso_date: IsoDate, dur: NominalDuration) -> FromYMDResult {
        self.to_trait_obj().date_add(iso_date, dur)
    }
}