use crate::cal::{
Buddhist, Chinese, Coptic, Dangi, Ethiopian, EthiopianEraStyle, Gregorian, Hebrew, HijriCivil,
HijriObservational, HijriTabular, HijriUmmAlQura, Indian, Iso, Japanese, JapaneseExtended,
Persian, Roc,
};
use crate::error::DateError;
use crate::{types, AsCalendar, Calendar, Date, DateDuration, DateDurationUnit, Ref};
use crate::preferences::{CalendarAlgorithm, HijriCalendarAlgorithm};
use icu_locale_core::preferences::define_preferences;
use icu_locale_core::subtags::language;
use icu_provider::prelude::*;
use core::fmt;
define_preferences!(
[Copy]
AnyCalendarPreferences,
{
calendar_algorithm: CalendarAlgorithm
}
);
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum AnyCalendar {
Buddhist(Buddhist),
Chinese(Chinese),
Coptic(Coptic),
Dangi(Dangi),
Ethiopian(Ethiopian),
Gregorian(Gregorian),
Hebrew(Hebrew),
Indian(Indian),
HijriCivil(HijriCivil),
HijriObservational(HijriObservational),
HijriTabular(HijriTabular),
HijriUmmAlQura(HijriUmmAlQura),
Iso(Iso),
Japanese(Japanese),
JapaneseExtended(JapaneseExtended),
Persian(Persian),
Roc(Roc),
}
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
#[non_exhaustive]
pub enum AnyDateInner {
Buddhist(<Buddhist as Calendar>::DateInner),
Chinese(<Chinese as Calendar>::DateInner),
Coptic(<Coptic as Calendar>::DateInner),
Dangi(<Dangi as Calendar>::DateInner),
Ethiopian(<Ethiopian as Calendar>::DateInner),
Gregorian(<Gregorian as Calendar>::DateInner),
Hebrew(<Hebrew as Calendar>::DateInner),
Indian(<Indian as Calendar>::DateInner),
HijriCivil(<HijriCivil as Calendar>::DateInner),
HijriObservational(<HijriObservational as Calendar>::DateInner),
HijriTabular(<HijriTabular as Calendar>::DateInner),
HijriUmmAlQura(<HijriUmmAlQura as Calendar>::DateInner),
Iso(<Iso as Calendar>::DateInner),
Japanese(<Japanese as Calendar>::DateInner),
JapaneseExtended(<JapaneseExtended as Calendar>::DateInner),
Persian(<Persian as Calendar>::DateInner),
Roc(<Roc as Calendar>::DateInner),
}
macro_rules! match_cal_and_date {
(match ($cal:ident, $date:ident): ($cal_matched:ident, $date_matched:ident) => $e:expr) => {
match ($cal, $date) {
(&Self::Buddhist(ref $cal_matched), &AnyDateInner::Buddhist(ref $date_matched)) => $e,
(&Self::Chinese(ref $cal_matched), &AnyDateInner::Chinese(ref $date_matched)) => $e,
(&Self::Coptic(ref $cal_matched), &AnyDateInner::Coptic(ref $date_matched)) => $e,
(&Self::Dangi(ref $cal_matched), &AnyDateInner::Dangi(ref $date_matched)) => $e,
(&Self::Ethiopian(ref $cal_matched), &AnyDateInner::Ethiopian(ref $date_matched)) => $e,
(&Self::Gregorian(ref $cal_matched), &AnyDateInner::Gregorian(ref $date_matched)) => $e,
(&Self::Hebrew(ref $cal_matched), &AnyDateInner::Hebrew(ref $date_matched)) => $e,
(&Self::Indian(ref $cal_matched), &AnyDateInner::Indian(ref $date_matched)) => $e,
(&Self::HijriCivil(ref $cal_matched), &AnyDateInner::HijriCivil(ref $date_matched)) => {
$e
}
(
&Self::HijriObservational(ref $cal_matched),
&AnyDateInner::HijriObservational(ref $date_matched),
) => $e,
(
&Self::HijriTabular(ref $cal_matched),
&AnyDateInner::HijriTabular(ref $date_matched),
) => $e,
(
&Self::HijriUmmAlQura(ref $cal_matched),
&AnyDateInner::HijriUmmAlQura(ref $date_matched),
) => $e,
(&Self::Iso(ref $cal_matched), &AnyDateInner::Iso(ref $date_matched)) => $e,
(&Self::Japanese(ref $cal_matched), &AnyDateInner::Japanese(ref $date_matched)) => $e,
(
&Self::JapaneseExtended(ref $cal_matched),
&AnyDateInner::JapaneseExtended(ref $date_matched),
) => $e,
(&Self::Persian(ref $cal_matched), &AnyDateInner::Persian(ref $date_matched)) => $e,
(&Self::Roc(ref $cal_matched), &AnyDateInner::Roc(ref $date_matched)) => $e,
_ => panic!(
"Found AnyCalendar with mixed calendar type {:?} and date type {:?}!",
$cal.kind().debug_name(),
$date.kind().debug_name()
),
}
};
}
impl Calendar for AnyCalendar {
type DateInner = AnyDateInner;
fn date_from_codes(
&self,
era: Option<&str>,
year: i32,
month_code: types::MonthCode,
day: u8,
) -> Result<Self::DateInner, DateError> {
let ret = match *self {
Self::Buddhist(ref c) => {
AnyDateInner::Buddhist(c.date_from_codes(era, year, month_code, day)?)
}
Self::Chinese(ref c) => {
AnyDateInner::Chinese(c.date_from_codes(era, year, month_code, day)?)
}
Self::Coptic(ref c) => {
AnyDateInner::Coptic(c.date_from_codes(era, year, month_code, day)?)
}
Self::Dangi(ref c) => {
AnyDateInner::Dangi(c.date_from_codes(era, year, month_code, day)?)
}
Self::Ethiopian(ref c) => {
AnyDateInner::Ethiopian(c.date_from_codes(era, year, month_code, day)?)
}
Self::Gregorian(ref c) => {
AnyDateInner::Gregorian(c.date_from_codes(era, year, month_code, day)?)
}
Self::Hebrew(ref c) => {
AnyDateInner::Hebrew(c.date_from_codes(era, year, month_code, day)?)
}
Self::Indian(ref c) => {
AnyDateInner::Indian(c.date_from_codes(era, year, month_code, day)?)
}
Self::HijriCivil(ref c) => {
AnyDateInner::HijriCivil(c.date_from_codes(era, year, month_code, day)?)
}
Self::HijriObservational(ref c) => {
AnyDateInner::HijriObservational(c.date_from_codes(era, year, month_code, day)?)
}
Self::HijriTabular(ref c) => {
AnyDateInner::HijriTabular(c.date_from_codes(era, year, month_code, day)?)
}
Self::HijriUmmAlQura(ref c) => {
AnyDateInner::HijriUmmAlQura(c.date_from_codes(era, year, month_code, day)?)
}
Self::Iso(ref c) => AnyDateInner::Iso(c.date_from_codes(era, year, month_code, day)?),
Self::Japanese(ref c) => {
AnyDateInner::Japanese(c.date_from_codes(era, year, month_code, day)?)
}
Self::JapaneseExtended(ref c) => {
AnyDateInner::JapaneseExtended(c.date_from_codes(era, year, month_code, day)?)
}
Self::Persian(ref c) => {
AnyDateInner::Persian(c.date_from_codes(era, year, month_code, day)?)
}
Self::Roc(ref c) => AnyDateInner::Roc(c.date_from_codes(era, year, month_code, day)?),
};
Ok(ret)
}
fn date_from_iso(&self, iso: Date<Iso>) -> AnyDateInner {
match *self {
Self::Buddhist(ref c) => AnyDateInner::Buddhist(c.date_from_iso(iso)),
Self::Chinese(ref c) => AnyDateInner::Chinese(c.date_from_iso(iso)),
Self::Coptic(ref c) => AnyDateInner::Coptic(c.date_from_iso(iso)),
Self::Dangi(ref c) => AnyDateInner::Dangi(c.date_from_iso(iso)),
Self::Ethiopian(ref c) => AnyDateInner::Ethiopian(c.date_from_iso(iso)),
Self::Gregorian(ref c) => AnyDateInner::Gregorian(c.date_from_iso(iso)),
Self::Hebrew(ref c) => AnyDateInner::Hebrew(c.date_from_iso(iso)),
Self::Indian(ref c) => AnyDateInner::Indian(c.date_from_iso(iso)),
Self::HijriCivil(ref c) => AnyDateInner::HijriCivil(c.date_from_iso(iso)),
Self::HijriObservational(ref c) => {
AnyDateInner::HijriObservational(c.date_from_iso(iso))
}
Self::HijriTabular(ref c) => AnyDateInner::HijriTabular(c.date_from_iso(iso)),
Self::HijriUmmAlQura(ref c) => AnyDateInner::HijriUmmAlQura(c.date_from_iso(iso)),
Self::Iso(ref c) => AnyDateInner::Iso(c.date_from_iso(iso)),
Self::Japanese(ref c) => AnyDateInner::Japanese(c.date_from_iso(iso)),
Self::JapaneseExtended(ref c) => AnyDateInner::JapaneseExtended(c.date_from_iso(iso)),
Self::Persian(ref c) => AnyDateInner::Persian(c.date_from_iso(iso)),
Self::Roc(ref c) => AnyDateInner::Roc(c.date_from_iso(iso)),
}
}
fn date_to_iso(&self, date: &Self::DateInner) -> Date<Iso> {
match_cal_and_date!(match (self, date): (c, d) => c.date_to_iso(d))
}
fn months_in_year(&self, date: &Self::DateInner) -> u8 {
match_cal_and_date!(match (self, date): (c, d) => c.months_in_year(d))
}
fn days_in_year(&self, date: &Self::DateInner) -> u16 {
match_cal_and_date!(match (self, date): (c, d) => c.days_in_year(d))
}
fn days_in_month(&self, date: &Self::DateInner) -> u8 {
match_cal_and_date!(match (self, date): (c, d) => c.days_in_month(d))
}
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
match (self, date) {
(Self::Buddhist(c), &mut AnyDateInner::Buddhist(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Chinese(c), &mut AnyDateInner::Chinese(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Coptic(c), &mut AnyDateInner::Coptic(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Dangi(c), &mut AnyDateInner::Dangi(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Ethiopian(c), &mut AnyDateInner::Ethiopian(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Gregorian(c), &mut AnyDateInner::Gregorian(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Hebrew(c), &mut AnyDateInner::Hebrew(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Indian(c), &mut AnyDateInner::Indian(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::HijriCivil(c), &mut AnyDateInner::HijriCivil(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::HijriObservational(c), &mut AnyDateInner::HijriObservational(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::HijriTabular(c), &mut AnyDateInner::HijriTabular(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::HijriUmmAlQura(c), &mut AnyDateInner::HijriUmmAlQura(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Iso(c), &mut AnyDateInner::Iso(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Japanese(c), &mut AnyDateInner::Japanese(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::JapaneseExtended(c), &mut AnyDateInner::JapaneseExtended(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Persian(c), &mut AnyDateInner::Persian(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
(Self::Roc(c), &mut AnyDateInner::Roc(ref mut d)) => {
c.offset_date(d, offset.cast_unit())
}
#[allow(clippy::panic)]
(_, d) => panic!(
"Found AnyCalendar with mixed calendar type {} and date type {}!",
self.kind().debug_name(),
d.kind().debug_name()
),
}
}
fn until(
&self,
date1: &Self::DateInner,
date2: &Self::DateInner,
calendar2: &Self,
largest_unit: DateDurationUnit,
smallest_unit: DateDurationUnit,
) -> DateDuration<Self> {
match (self, calendar2, date1, date2) {
(
Self::Buddhist(c1),
Self::Buddhist(c2),
AnyDateInner::Buddhist(d1),
AnyDateInner::Buddhist(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Chinese(c1),
Self::Chinese(c2),
AnyDateInner::Chinese(d1),
AnyDateInner::Chinese(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Coptic(c1),
Self::Coptic(c2),
AnyDateInner::Coptic(d1),
AnyDateInner::Coptic(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Dangi(c1),
Self::Dangi(c2),
AnyDateInner::Dangi(d1),
AnyDateInner::Dangi(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Ethiopian(c1),
Self::Ethiopian(c2),
AnyDateInner::Ethiopian(d1),
AnyDateInner::Ethiopian(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Gregorian(c1),
Self::Gregorian(c2),
AnyDateInner::Gregorian(d1),
AnyDateInner::Gregorian(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Hebrew(c1),
Self::Hebrew(c2),
AnyDateInner::Hebrew(d1),
AnyDateInner::Hebrew(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Indian(c1),
Self::Indian(c2),
AnyDateInner::Indian(d1),
AnyDateInner::Indian(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::HijriCivil(c1),
Self::HijriCivil(c2),
AnyDateInner::HijriCivil(d1),
AnyDateInner::HijriCivil(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::HijriObservational(c1),
Self::HijriObservational(c2),
AnyDateInner::HijriObservational(d1),
AnyDateInner::HijriObservational(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::HijriTabular(c1),
Self::HijriTabular(c2),
AnyDateInner::HijriTabular(d1),
AnyDateInner::HijriTabular(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::HijriUmmAlQura(c1),
Self::HijriUmmAlQura(c2),
AnyDateInner::HijriUmmAlQura(d1),
AnyDateInner::HijriUmmAlQura(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(Self::Iso(c1), Self::Iso(c2), AnyDateInner::Iso(d1), AnyDateInner::Iso(d2)) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Japanese(c1),
Self::Japanese(c2),
AnyDateInner::Japanese(d1),
AnyDateInner::Japanese(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::JapaneseExtended(c1),
Self::JapaneseExtended(c2),
AnyDateInner::JapaneseExtended(d1),
AnyDateInner::JapaneseExtended(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(
Self::Persian(c1),
Self::Persian(c2),
AnyDateInner::Persian(d1),
AnyDateInner::Persian(d2),
) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
(Self::Roc(c1), Self::Roc(c2), AnyDateInner::Roc(d1), AnyDateInner::Roc(d2)) => c1
.until(d1, d2, c2, largest_unit, smallest_unit)
.cast_unit(),
_ => {
let iso = calendar2.date_to_iso(date2);
match_cal_and_date!(match (self, date1):
(c1, d1) => {
let d2 = c1.date_from_iso(iso);
let until = c1.until(d1, &d2, c1, largest_unit, smallest_unit);
until.cast_unit::<AnyCalendar>()
}
)
}
}
}
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
match_cal_and_date!(match (self, date): (c, d) => c.year(d))
}
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
match_cal_and_date!(match (self, date): (c, d) => c.is_in_leap_year(d))
}
fn month(&self, date: &Self::DateInner) -> types::MonthInfo {
match_cal_and_date!(match (self, date): (c, d) => c.month(d))
}
fn day_of_month(&self, date: &Self::DateInner) -> types::DayOfMonth {
match_cal_and_date!(match (self, date): (c, d) => c.day_of_month(d))
}
fn day_of_year_info(&self, date: &Self::DateInner) -> types::DayOfYearInfo {
match_cal_and_date!(match (self, date): (c, d) => c.day_of_year_info(d))
}
fn debug_name(&self) -> &'static str {
match *self {
Self::Buddhist(_) => "AnyCalendar (Buddhist)",
Self::Chinese(_) => "AnyCalendar (Chinese)",
Self::Coptic(_) => "AnyCalendar (Coptic)",
Self::Dangi(_) => "AnyCalendar (Dangi)",
Self::Ethiopian(_) => "AnyCalendar (Ethiopian)",
Self::Gregorian(_) => "AnyCalendar (Gregorian)",
Self::Hebrew(_) => "AnyCalendar (Hebrew)",
Self::Indian(_) => "AnyCalendar (Indian)",
Self::HijriCivil(_) => "AnyCalendar (Hijri, civil)",
Self::HijriObservational(_) => "AnyCalendar (Hijri, observational)",
Self::HijriTabular(_) => "AnyCalendar (Hijri, tabular)",
Self::HijriUmmAlQura(_) => "AnyCalendar (Hijri, Umm al-Qura)",
Self::Iso(_) => "AnyCalendar (Iso)",
Self::Japanese(_) => "AnyCalendar (Japanese)",
Self::JapaneseExtended(_) => "AnyCalendar (Japanese, historical era data)",
Self::Persian(_) => "AnyCalendar (Persian)",
Self::Roc(_) => "AnyCalendar (Roc)",
}
}
fn any_calendar_kind(&self) -> Option<AnyCalendarKind> {
Some(self.kind())
}
}
impl AnyCalendar {
#[cfg(feature = "compiled_data")]
pub const fn new_for_kind(kind: AnyCalendarKind) -> Self {
match kind {
AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
AnyCalendarKind::Chinese => AnyCalendar::Chinese(Chinese::new()),
AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
AnyCalendarKind::Dangi => AnyCalendar::Dangi(Dangi::new()),
AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
EthiopianEraStyle::AmeteMihret,
)),
AnyCalendarKind::EthiopianAmeteAlem => {
AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
}
AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
AnyCalendarKind::HijriCivil => AnyCalendar::HijriCivil(HijriCivil),
AnyCalendarKind::HijriObservational => {
AnyCalendar::HijriObservational(HijriObservational::new())
}
AnyCalendarKind::HijriTabular => AnyCalendar::HijriTabular(HijriTabular),
AnyCalendarKind::HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(HijriUmmAlQura::new()),
AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
AnyCalendarKind::Japanese => AnyCalendar::Japanese(Japanese::new()),
AnyCalendarKind::JapaneseExtended => {
AnyCalendar::JapaneseExtended(JapaneseExtended::new())
}
AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
}
}
#[cfg(feature = "serde")]
#[doc = icu_provider::gen_buffer_unstable_docs!(BUFFER, Self::new_for_kind)]
pub fn try_new_for_kind_with_buffer_provider<P>(
provider: &P,
kind: AnyCalendarKind,
) -> Result<Self, DataError>
where
P: BufferProvider + ?Sized,
{
Ok(match kind {
AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
AnyCalendarKind::Chinese => {
AnyCalendar::Chinese(Chinese::try_new_with_buffer_provider(provider)?)
}
AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
AnyCalendarKind::Dangi => {
AnyCalendar::Dangi(Dangi::try_new_with_buffer_provider(provider)?)
}
AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
EthiopianEraStyle::AmeteMihret,
)),
AnyCalendarKind::EthiopianAmeteAlem => {
AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
}
AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
AnyCalendarKind::HijriCivil => AnyCalendar::HijriCivil(HijriCivil),
AnyCalendarKind::HijriObservational => AnyCalendar::HijriObservational(
HijriObservational::try_new_with_buffer_provider(provider)?,
),
AnyCalendarKind::HijriTabular => AnyCalendar::HijriTabular(HijriTabular),
AnyCalendarKind::HijriUmmAlQura => {
AnyCalendar::HijriUmmAlQura(HijriUmmAlQura::try_new_with_buffer_provider(provider)?)
}
AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
AnyCalendarKind::Japanese => {
AnyCalendar::Japanese(Japanese::try_new_with_buffer_provider(provider)?)
}
AnyCalendarKind::JapaneseExtended => AnyCalendar::JapaneseExtended(
JapaneseExtended::try_new_with_buffer_provider(provider)?,
),
AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
})
}
#[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::new_for_kind)]
pub fn try_new_for_kind_unstable<P>(
provider: &P,
kind: AnyCalendarKind,
) -> Result<Self, DataError>
where
P: DataProvider<crate::provider::CalendarJapaneseModernV1>
+ DataProvider<crate::provider::CalendarJapaneseExtendedV1>
+ DataProvider<crate::provider::CalendarChineseV1>
+ DataProvider<crate::provider::CalendarDangiV1>
+ DataProvider<crate::provider::CalendarHijriObservationalV1>
+ DataProvider<crate::provider::CalendarHijriUmmalquraV1>
+ ?Sized,
{
Ok(match kind {
AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
AnyCalendarKind::Chinese => AnyCalendar::Chinese(Chinese::try_new_unstable(provider)?),
AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
AnyCalendarKind::Dangi => AnyCalendar::Dangi(Dangi::try_new_unstable(provider)?),
AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
EthiopianEraStyle::AmeteMihret,
)),
AnyCalendarKind::EthiopianAmeteAlem => {
AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
}
AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
AnyCalendarKind::HijriCivil => AnyCalendar::HijriCivil(HijriCivil),
AnyCalendarKind::HijriObservational => {
AnyCalendar::HijriObservational(HijriObservational::try_new_unstable(provider)?)
}
AnyCalendarKind::HijriTabular => AnyCalendar::HijriTabular(HijriTabular),
AnyCalendarKind::HijriUmmAlQura => {
AnyCalendar::HijriUmmAlQura(HijriUmmAlQura::try_new_unstable(provider)?)
}
AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
AnyCalendarKind::Japanese => {
AnyCalendar::Japanese(Japanese::try_new_unstable(provider)?)
}
AnyCalendarKind::JapaneseExtended => {
AnyCalendar::JapaneseExtended(JapaneseExtended::try_new_unstable(provider)?)
}
AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
})
}
#[cfg(feature = "compiled_data")]
pub fn try_new(prefs: AnyCalendarPreferences) -> Result<Self, DataError> {
Self::try_new_unstable(&crate::provider::Baked, prefs)
}
icu_provider::gen_buffer_data_constructors!(
(prefs: AnyCalendarPreferences) -> error: DataError,
functions: [
try_new: skip,
try_new_with_buffer_provider,
try_new_unstable,
Self,
]
);
#[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable<P>(
provider: &P,
prefs: AnyCalendarPreferences,
) -> Result<Self, DataError>
where
P: DataProvider<crate::provider::CalendarJapaneseModernV1>
+ DataProvider<crate::provider::CalendarJapaneseExtendedV1>
+ DataProvider<crate::provider::CalendarChineseV1>
+ DataProvider<crate::provider::CalendarDangiV1>
+ DataProvider<crate::provider::CalendarHijriObservationalV1>
+ DataProvider<crate::provider::CalendarHijriUmmalquraV1>
+ ?Sized,
{
let algo = prefs.calendar_algorithm.unwrap_or_else(|| {
let lang = prefs.locale_preferences.language();
if lang == language!("th") {
CalendarAlgorithm::Buddhist
} else if lang == language!("sa") {
CalendarAlgorithm::Hijri(Some(HijriCalendarAlgorithm::Umalqura))
} else if lang == language!("af") || lang == language!("ir") {
CalendarAlgorithm::Persian
} else {
CalendarAlgorithm::Gregory
}
});
let kind = if let Ok(kind) = algo.try_into() {
kind
} else {
debug_assert!(false, "unsupported calendar algorithm {algo:?}");
AnyCalendarKind::Gregorian
};
Self::try_new_for_kind_unstable(provider, kind)
}
pub fn kind(&self) -> AnyCalendarKind {
match *self {
Self::Buddhist(_) => AnyCalendarKind::Buddhist,
Self::Chinese(_) => AnyCalendarKind::Chinese,
Self::Coptic(_) => AnyCalendarKind::Coptic,
Self::Dangi(_) => AnyCalendarKind::Dangi,
Self::Ethiopian(ref e) => IntoAnyCalendar::kind(e),
Self::Gregorian(_) => AnyCalendarKind::Gregorian,
Self::Hebrew(_) => AnyCalendarKind::Hebrew,
Self::Indian(_) => AnyCalendarKind::Indian,
Self::HijriCivil(_) => AnyCalendarKind::HijriCivil,
Self::HijriObservational(_) => AnyCalendarKind::HijriObservational,
Self::HijriTabular(_) => AnyCalendarKind::HijriTabular,
Self::HijriUmmAlQura(_) => AnyCalendarKind::HijriUmmAlQura,
Self::Iso(_) => AnyCalendarKind::Iso,
Self::Japanese(_) => AnyCalendarKind::Japanese,
Self::JapaneseExtended(_) => AnyCalendarKind::JapaneseExtended,
Self::Persian(_) => AnyCalendarKind::Persian,
Self::Roc(_) => AnyCalendarKind::Roc,
}
}
pub fn convert_any_date<'a>(
&'a self,
date: &Date<impl AsCalendar<Calendar = AnyCalendar>>,
) -> Date<Ref<'a, AnyCalendar>> {
if self.kind() != date.calendar.as_calendar().kind() {
Date::new_from_iso(date.to_iso(), Ref(self))
} else {
Date {
inner: date.inner,
calendar: Ref(self),
}
}
}
}
impl AnyDateInner {
fn kind(&self) -> AnyCalendarKind {
match *self {
AnyDateInner::Buddhist(_) => AnyCalendarKind::Buddhist,
AnyDateInner::Chinese(_) => AnyCalendarKind::Chinese,
AnyDateInner::Coptic(_) => AnyCalendarKind::Coptic,
AnyDateInner::Dangi(_) => AnyCalendarKind::Dangi,
AnyDateInner::Ethiopian(_) => AnyCalendarKind::Ethiopian,
AnyDateInner::Gregorian(_) => AnyCalendarKind::Gregorian,
AnyDateInner::Hebrew(_) => AnyCalendarKind::Hebrew,
AnyDateInner::Indian(_) => AnyCalendarKind::Indian,
AnyDateInner::HijriCivil(_) => AnyCalendarKind::HijriCivil,
AnyDateInner::HijriObservational(_) => AnyCalendarKind::HijriObservational,
AnyDateInner::HijriTabular(_) => AnyCalendarKind::HijriTabular,
AnyDateInner::HijriUmmAlQura(_) => AnyCalendarKind::HijriUmmAlQura,
AnyDateInner::Iso(_) => AnyCalendarKind::Iso,
AnyDateInner::Japanese(_) => AnyCalendarKind::Japanese,
AnyDateInner::JapaneseExtended(_) => AnyCalendarKind::JapaneseExtended,
AnyDateInner::Persian(_) => AnyCalendarKind::Persian,
AnyDateInner::Roc(_) => AnyCalendarKind::Roc,
}
}
}
#[non_exhaustive]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum AnyCalendarKind {
Buddhist,
Chinese,
Coptic,
Dangi,
Ethiopian,
EthiopianAmeteAlem,
Gregorian,
Hebrew,
Indian,
HijriCivil,
HijriObservational,
HijriTabular,
HijriUmmAlQura,
Iso,
Japanese,
JapaneseExtended,
Persian,
Roc,
}
impl AnyCalendarKind {
fn debug_name(self) -> &'static str {
match self {
AnyCalendarKind::Buddhist => Buddhist.debug_name(),
AnyCalendarKind::Chinese => Chinese::DEBUG_NAME,
AnyCalendarKind::Coptic => Coptic.debug_name(),
AnyCalendarKind::Dangi => Dangi::DEBUG_NAME,
AnyCalendarKind::Ethiopian => Ethiopian(false).debug_name(),
AnyCalendarKind::EthiopianAmeteAlem => Ethiopian(true).debug_name(),
AnyCalendarKind::Gregorian => Gregorian.debug_name(),
AnyCalendarKind::Hebrew => Hebrew.debug_name(),
AnyCalendarKind::Indian => Indian.debug_name(),
AnyCalendarKind::HijriCivil => HijriCivil.debug_name(),
AnyCalendarKind::HijriObservational => HijriObservational::DEBUG_NAME,
AnyCalendarKind::HijriTabular => HijriTabular.debug_name(),
AnyCalendarKind::HijriUmmAlQura => HijriUmmAlQura::DEBUG_NAME,
AnyCalendarKind::Iso => Iso.debug_name(),
AnyCalendarKind::Japanese => Japanese::DEBUG_NAME,
AnyCalendarKind::JapaneseExtended => JapaneseExtended::DEBUG_NAME,
AnyCalendarKind::Persian => Persian.debug_name(),
AnyCalendarKind::Roc => Roc.debug_name(),
}
}
}
impl TryFrom<CalendarAlgorithm> for AnyCalendarKind {
type Error = ();
fn try_from(v: CalendarAlgorithm) -> Result<Self, Self::Error> {
use CalendarAlgorithm::*;
match v {
Buddhist => Ok(AnyCalendarKind::Buddhist),
Chinese => Ok(AnyCalendarKind::Chinese),
Coptic => Ok(AnyCalendarKind::Coptic),
Dangi => Ok(AnyCalendarKind::Dangi),
Ethioaa => Ok(AnyCalendarKind::EthiopianAmeteAlem),
Ethiopic => Ok(AnyCalendarKind::Ethiopian),
Gregory => Ok(AnyCalendarKind::Gregorian),
Hebrew => Ok(AnyCalendarKind::Hebrew),
Indian => Ok(AnyCalendarKind::Indian),
Hijri(None) => Ok(AnyCalendarKind::HijriObservational),
Hijri(Some(HijriCalendarAlgorithm::Umalqura)) => Ok(AnyCalendarKind::HijriUmmAlQura),
Hijri(Some(HijriCalendarAlgorithm::Tbla)) => Ok(AnyCalendarKind::HijriTabular),
Hijri(Some(HijriCalendarAlgorithm::Civil)) => Ok(AnyCalendarKind::HijriCivil),
Hijri(Some(HijriCalendarAlgorithm::Rgsa)) => Err(()),
Iso8601 => Ok(AnyCalendarKind::Iso),
Japanese => Ok(AnyCalendarKind::Japanese),
Persian => Ok(AnyCalendarKind::Persian),
Roc => Ok(AnyCalendarKind::Roc),
_ => {
debug_assert!(false, "unknown calendar algorithm {v:?}");
Err(())
}
}
}
}
impl fmt::Display for AnyCalendarKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
pub trait IntoAnyCalendar: Calendar + Sized {
fn to_any(self) -> AnyCalendar;
fn kind(&self) -> AnyCalendarKind;
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar>;
fn from_any_ref(any: &AnyCalendar) -> Option<&Self>;
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner;
}
impl IntoAnyCalendar for AnyCalendar {
#[inline]
fn to_any(self) -> AnyCalendar {
self
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
self.kind()
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
Ok(any)
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
Some(any)
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
*d
}
}
impl IntoAnyCalendar for Buddhist {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Buddhist(Buddhist)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Buddhist
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Buddhist(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Buddhist(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Buddhist(*d)
}
}
impl From<Buddhist> for AnyCalendar {
fn from(value: Buddhist) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Chinese {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Chinese(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Chinese
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Chinese(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Chinese(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Chinese(*d)
}
}
impl From<Chinese> for AnyCalendar {
fn from(value: Chinese) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Coptic {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Coptic(Coptic)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Coptic
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Coptic(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Coptic(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Coptic(*d)
}
}
impl From<Coptic> for AnyCalendar {
fn from(value: Coptic) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Dangi {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Dangi(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Dangi
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Dangi(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Dangi(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Dangi(*d)
}
}
impl From<Dangi> for AnyCalendar {
fn from(value: Dangi) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Ethiopian {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Ethiopian(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
if self.0 {
AnyCalendarKind::EthiopianAmeteAlem
} else {
AnyCalendarKind::Ethiopian
}
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Ethiopian(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Ethiopian(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Ethiopian(*d)
}
}
impl From<Ethiopian> for AnyCalendar {
fn from(value: Ethiopian) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Gregorian {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Gregorian(Gregorian)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Gregorian
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Gregorian(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Gregorian(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Gregorian(*d)
}
}
impl From<Gregorian> for AnyCalendar {
fn from(value: Gregorian) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Hebrew {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Hebrew(Hebrew)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Hebrew
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Hebrew(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Hebrew(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Hebrew(*d)
}
}
impl From<Hebrew> for AnyCalendar {
fn from(value: Hebrew) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Indian {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Indian(Indian)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Indian
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Indian(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Indian(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Indian(*d)
}
}
impl From<Indian> for AnyCalendar {
fn from(value: Indian) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for HijriCivil {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::HijriCivil(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::HijriCivil
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::HijriCivil(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::HijriCivil(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::HijriCivil(*d)
}
}
impl From<HijriCivil> for AnyCalendar {
fn from(value: HijriCivil) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for HijriObservational {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::HijriObservational(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::HijriObservational
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::HijriObservational(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::HijriObservational(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::HijriObservational(*d)
}
}
impl From<HijriObservational> for AnyCalendar {
fn from(value: HijriObservational) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for HijriTabular {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::HijriTabular(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::HijriTabular
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::HijriTabular(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::HijriTabular(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::HijriTabular(*d)
}
}
impl From<HijriTabular> for AnyCalendar {
fn from(value: HijriTabular) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for HijriUmmAlQura {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::HijriUmmAlQura(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::HijriUmmAlQura
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::HijriUmmAlQura(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::HijriUmmAlQura(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::HijriUmmAlQura(*d)
}
}
impl From<HijriUmmAlQura> for AnyCalendar {
fn from(value: HijriUmmAlQura) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Iso {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Iso(Iso)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Iso
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Iso(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Iso(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Iso(*d)
}
}
impl From<Iso> for AnyCalendar {
fn from(value: Iso) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Japanese {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Japanese(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Japanese
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Japanese(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Japanese(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Japanese(*d)
}
}
impl From<Japanese> for AnyCalendar {
fn from(value: Japanese) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for JapaneseExtended {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::JapaneseExtended(self)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::JapaneseExtended
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::JapaneseExtended(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::JapaneseExtended(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::JapaneseExtended(*d)
}
}
impl From<JapaneseExtended> for AnyCalendar {
fn from(value: JapaneseExtended) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Persian {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Persian(Persian)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Persian
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Persian(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Persian(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Persian(*d)
}
}
impl From<Persian> for AnyCalendar {
fn from(value: Persian) -> AnyCalendar {
value.to_any()
}
}
impl IntoAnyCalendar for Roc {
#[inline]
fn to_any(self) -> AnyCalendar {
AnyCalendar::Roc(Roc)
}
#[inline]
fn kind(&self) -> AnyCalendarKind {
AnyCalendarKind::Roc
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Roc(cal) = any {
Ok(cal)
} else {
Err(any)
}
}
#[inline]
fn from_any_ref(any: &AnyCalendar) -> Option<&Self> {
if let AnyCalendar::Roc(cal) = any {
Some(cal)
} else {
None
}
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
AnyDateInner::Roc(*d)
}
}
impl From<Roc> for AnyCalendar {
fn from(value: Roc) -> AnyCalendar {
value.to_any()
}
}
#[cfg(test)]
mod tests {
use tinystr::tinystr;
use types::MonthCode;
use super::*;
use crate::Ref;
fn single_test_roundtrip(
calendar: Ref<AnyCalendar>,
era: &str,
year: i32,
month_code: &str,
day: u8,
) {
let month = types::MonthCode(month_code.parse().expect("month code must parse"));
let date =
Date::try_new_from_codes(Some(era), year, month, day, calendar).unwrap_or_else(|e| {
panic!(
"Failed to construct date for {} with {era:?}, {year}, {month}, {day}: {e:?}",
calendar.debug_name(),
)
});
let roundtrip_year = date.year();
let roundtrip_year = roundtrip_year.era_year_or_extended();
let roundtrip_month = date.month().standard_code;
let roundtrip_day = date.day_of_month().0;
assert_eq!(
(year, month, day),
(roundtrip_year, roundtrip_month, roundtrip_day),
"Failed to roundtrip for calendar {}",
calendar.debug_name()
);
let iso = date.to_iso();
let reconstructed = Date::new_from_iso(iso, calendar);
assert_eq!(
date, reconstructed,
"Failed to roundtrip via iso with {era:?}, {year}, {month}, {day}"
)
}
fn single_test_error(
calendar: Ref<AnyCalendar>,
era: &str,
year: i32,
month_code: &str,
day: u8,
error: DateError,
) {
let month = types::MonthCode(month_code.parse().expect("month code must parse"));
let date = Date::try_new_from_codes(Some(era), year, month, day, calendar);
assert_eq!(
date,
Err(error),
"Construction with {era:?}, {year}, {month}, {day} did not return {error:?}"
)
}
#[test]
fn test_any_construction() {
let buddhist = AnyCalendar::new_for_kind(AnyCalendarKind::Buddhist);
let chinese = AnyCalendar::new_for_kind(AnyCalendarKind::Chinese);
let coptic = AnyCalendar::new_for_kind(AnyCalendarKind::Coptic);
let dangi = AnyCalendar::new_for_kind(AnyCalendarKind::Dangi);
let ethioaa = AnyCalendar::new_for_kind(AnyCalendarKind::EthiopianAmeteAlem);
let ethiopian = AnyCalendar::new_for_kind(AnyCalendarKind::Ethiopian);
let gregorian = AnyCalendar::new_for_kind(AnyCalendarKind::Gregorian);
let hebrew = AnyCalendar::new_for_kind(AnyCalendarKind::Hebrew);
let indian = AnyCalendar::new_for_kind(AnyCalendarKind::Indian);
let hijri_civil: AnyCalendar = AnyCalendar::new_for_kind(AnyCalendarKind::HijriCivil);
let hijri_observational: AnyCalendar =
AnyCalendar::new_for_kind(AnyCalendarKind::HijriObservational);
let hijri_tabular: AnyCalendar = AnyCalendar::new_for_kind(AnyCalendarKind::HijriTabular);
let hijri_umm_al_qura: AnyCalendar =
AnyCalendar::new_for_kind(AnyCalendarKind::HijriUmmAlQura);
let japanese = AnyCalendar::new_for_kind(AnyCalendarKind::Japanese);
let japanext = AnyCalendar::new_for_kind(AnyCalendarKind::JapaneseExtended);
let persian = AnyCalendar::new_for_kind(AnyCalendarKind::Persian);
let roc = AnyCalendar::new_for_kind(AnyCalendarKind::Roc);
let buddhist = Ref(&buddhist);
let chinese = Ref(&chinese);
let coptic = Ref(&coptic);
let dangi = Ref(&dangi);
let ethioaa = Ref(ðioaa);
let ethiopian = Ref(ðiopian);
let gregorian = Ref(&gregorian);
let hebrew = Ref(&hebrew);
let indian = Ref(&indian);
let hijri_civil = Ref(&hijri_civil);
let hijri_observational = Ref(&hijri_observational);
let hijri_tabular = Ref(&hijri_tabular);
let hijri_umm_al_qura = Ref(&hijri_umm_al_qura);
let japanese = Ref(&japanese);
let japanext = Ref(&japanext);
let persian = Ref(&persian);
let roc = Ref(&roc);
single_test_roundtrip(buddhist, "be", 100, "M03", 1);
single_test_roundtrip(buddhist, "be", 2000, "M03", 1);
single_test_roundtrip(buddhist, "be", -100, "M03", 1);
single_test_error(
buddhist,
"be",
100,
"M13",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
);
single_test_roundtrip(coptic, "coptic", 100, "M03", 1);
single_test_roundtrip(coptic, "coptic", 2000, "M03", 1);
single_test_roundtrip(coptic, "coptic", 100, "M13", 1);
single_test_error(
coptic,
"coptic",
100,
"M14",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M14"))),
);
single_test_error(
coptic,
"coptic",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
coptic,
"coptic-inverse",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_roundtrip(ethiopian, "incar", 100, "M03", 1);
single_test_roundtrip(ethiopian, "incar", 2000, "M03", 1);
single_test_roundtrip(ethiopian, "incar", 2000, "M13", 1);
single_test_error(
ethiopian,
"incar",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
ethiopian,
"mundi",
5600,
"M03",
1,
DateError::Range {
field: "year",
value: 5600,
min: i32::MIN,
max: 5500,
},
);
single_test_error(
ethiopian,
"incar",
100,
"M14",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M14"))),
);
single_test_roundtrip(ethioaa, "mundi", 7000, "M13", 1);
single_test_roundtrip(ethioaa, "mundi", 7000, "M13", 1);
single_test_error(
ethiopian,
"mundi",
100,
"M14",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M14"))),
);
single_test_roundtrip(gregorian, "ce", 100, "M03", 1);
single_test_roundtrip(gregorian, "ce", 2000, "M03", 1);
single_test_roundtrip(gregorian, "bce", 100, "M03", 1);
single_test_error(
gregorian,
"ce",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
gregorian,
"bce",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
gregorian,
"bce",
100,
"M13",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
);
single_test_roundtrip(indian, "saka", 100, "M03", 1);
single_test_roundtrip(indian, "saka", 2000, "M12", 1);
single_test_roundtrip(indian, "saka", -100, "M03", 1);
single_test_roundtrip(indian, "saka", 0, "M03", 1);
single_test_error(
indian,
"saka",
100,
"M13",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
);
single_test_roundtrip(chinese, "chinese", 400, "M02", 5);
single_test_roundtrip(chinese, "chinese", 4660, "M07", 29);
single_test_roundtrip(chinese, "chinese", -100, "M11", 12);
single_test_error(
chinese,
"chinese",
4658,
"M13",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
);
single_test_roundtrip(dangi, "dangi", 400, "M02", 5);
single_test_roundtrip(dangi, "dangi", 4660, "M08", 29);
single_test_roundtrip(dangi, "dangi", -1300, "M11", 12);
single_test_error(
dangi,
"dangi",
10393,
"M00L",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M00L"))),
);
single_test_roundtrip(japanese, "reiwa", 3, "M03", 1);
single_test_roundtrip(japanese, "heisei", 6, "M12", 1);
single_test_roundtrip(japanese, "meiji", 10, "M03", 1);
single_test_roundtrip(japanese, "ce", 1000, "M03", 1);
single_test_roundtrip(japanese, "bce", 10, "M03", 1);
single_test_error(
japanese,
"ce",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
japanese,
"bce",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
japanese,
"reiwa",
2,
"M13",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
);
single_test_roundtrip(japanext, "reiwa", 3, "M03", 1);
single_test_roundtrip(japanext, "heisei", 6, "M12", 1);
single_test_roundtrip(japanext, "meiji", 10, "M03", 1);
single_test_roundtrip(japanext, "tenpyokampo-749", 1, "M04", 20);
single_test_roundtrip(japanext, "ce", 100, "M03", 1);
single_test_roundtrip(japanext, "bce", 10, "M03", 1);
single_test_error(
japanext,
"ce",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
japanext,
"bce",
0,
"M03",
1,
DateError::Range {
field: "year",
value: 0,
min: 1,
max: i32::MAX,
},
);
single_test_error(
japanext,
"reiwa",
2,
"M13",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M13"))),
);
single_test_roundtrip(persian, "ap", 477, "M03", 1);
single_test_roundtrip(persian, "ap", 2083, "M07", 21);
single_test_roundtrip(persian, "ap", 1600, "M12", 20);
single_test_error(
persian,
"ap",
100,
"M9",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
);
single_test_roundtrip(hebrew, "hebrew", 5773, "M03", 1);
single_test_roundtrip(hebrew, "hebrew", 4993, "M07", 21);
single_test_roundtrip(hebrew, "hebrew", 5012, "M12", 20);
single_test_error(
hebrew,
"hebrew",
100,
"M9",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
);
single_test_roundtrip(roc, "roc", 10, "M05", 3);
single_test_roundtrip(roc, "roc-inverse", 15, "M01", 10);
single_test_roundtrip(roc, "roc", 100, "M10", 30);
single_test_roundtrip(hijri_observational, "ah", 477, "M03", 1);
single_test_roundtrip(hijri_observational, "ah", 2083, "M07", 21);
single_test_roundtrip(hijri_observational, "ah", 1600, "M12", 20);
single_test_error(
hijri_observational,
"ah",
100,
"M9",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
);
single_test_roundtrip(hijri_civil, "ah", 477, "M03", 1);
single_test_roundtrip(hijri_civil, "ah", 2083, "M07", 21);
single_test_roundtrip(hijri_civil, "ah", 1600, "M12", 20);
single_test_error(
hijri_civil,
"ah",
100,
"M9",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
);
single_test_roundtrip(hijri_umm_al_qura, "ah", 477, "M03", 1);
single_test_roundtrip(hijri_umm_al_qura, "ah", 2083, "M07", 21);
single_test_roundtrip(hijri_umm_al_qura, "ah", 1600, "M12", 20);
single_test_error(
hijri_umm_al_qura,
"ah",
100,
"M9",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
);
single_test_roundtrip(hijri_tabular, "ah", 477, "M03", 1);
single_test_roundtrip(hijri_tabular, "ah", 2083, "M07", 21);
single_test_roundtrip(hijri_tabular, "ah", 1600, "M12", 20);
single_test_error(
hijri_tabular,
"ah",
100,
"M9",
1,
DateError::UnknownMonthCode(MonthCode(tinystr!(4, "M9"))),
);
}
}