diff --git a/components/calendar/src/calendar_arithmetic.rs b/components/calendar/src/calendar_arithmetic.rs index c81c5734651..494930dedc4 100644 --- a/components/calendar/src/calendar_arithmetic.rs +++ b/components/calendar/src/calendar_arithmetic.rs @@ -44,10 +44,10 @@ pub trait CalendarArithmetic: Calendar { /// /// The name has `provided` in it to avoid clashes with Calendar fn days_in_provided_year(year: i32, data: &Self::PrecomputedData) -> u16 { - let months_in_year = Self::months_for_every_year(year); + let months_in_year = Self::months_for_every_year(year, data); let mut days: u16 = 0; for month in 1..=months_in_year { - days += Self::month_days(year, month) as u16; + days += Self::month_days(year, month, data) as u16; } days } @@ -174,7 +174,11 @@ impl ArithmeticDate { } #[inline] - pub fn date_from_year_day_with_data(year: i32, year_day: u32, data: &C::PrecomputedData) -> ArithmeticDate { + pub fn date_from_year_day_with_data( + year: i32, + year_day: u32, + data: &C::PrecomputedData, + ) -> ArithmeticDate { let mut month = 1; let mut day = year_day as i32; while month <= C::months_for_every_year(year, data) { @@ -310,18 +314,17 @@ impl ArithmeticDate { day: u8, data: &C::PrecomputedData, ) -> Result { - Self::new_from_ordinals(year, month, day, data) + Self::new_from_ordinals_with_data(year, month, day, data) } } - /// Convenience methods for dataless calendars (the majority) /// /// May be removed in the long run impl> ArithmeticDate { #[inline] pub fn max_date() -> Self { - self.max_date_with_data(&()) + Self::max_date_with_data(&()) } #[inline] @@ -391,21 +394,13 @@ impl> ArithmeticDate { /// Construct a new arithmetic date from a year, month ordinal, and day, bounds checking /// the month and day /// Originally (new_from_solar_ordinals) but renamed because it works for some lunar calendars - pub fn new_from_ordinals( - year: i32, - month: u8, - day: u8, - ) -> Result { + pub fn new_from_ordinals(year: i32, month: u8, day: u8) -> Result { Self::new_from_ordinals_with_data(year, month, day, &()) } /// This fn currently just calls [`new_from_ordinals`], but exists separately for /// lunar calendars in case different logic needs to be implemented later. - pub fn new_from_lunar_ordinals( - year: i32, - month: u8, - day: u8, - ) -> Result { + pub fn new_from_lunar_ordinals(year: i32, month: u8, day: u8) -> Result { Self::new_from_lunar_ordinals_with_data(year, month, day, &()) } } diff --git a/components/calendar/src/chinese.rs b/components/calendar/src/chinese.rs index e6b021ce45d..7b7e095cf7c 100644 --- a/components/calendar/src/chinese.rs +++ b/components/calendar/src/chinese.rs @@ -227,7 +227,7 @@ impl Calendar for Chinese { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0 .0.year) + Self::is_leap_year(date.0 .0.year, &()) } /// The calendar-specific month code represented by `date`; @@ -308,7 +308,7 @@ impl Calendar for Chinese { day_of_year: date.0.day_of_year(), days_in_year: date.0.days_in_year_inner(), prev_year: Self::format_chinese_year(prev_year, None), - days_in_prev_year: Self::days_in_provided_year(prev_year), + days_in_prev_year: Self::days_in_provided_year(prev_year, &()), next_year: Self::format_chinese_year(next_year, None), } } diff --git a/components/calendar/src/chinese_based.rs b/components/calendar/src/chinese_based.rs index a99aed496e9..b40091dd998 100644 --- a/components/calendar/src/chinese_based.rs +++ b/components/calendar/src/chinese_based.rs @@ -467,14 +467,14 @@ impl ChineseBasedDateInner { } impl CalendarArithmetic for C { - type Cache = (); - fn month_days(year: i32, month: u8, cache: &()) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &Self::PrecomputedData) -> u8 { chinese_based::month_days::(year, month) } /// Returns the number of months in a given year, which is 13 in a leap year, and 12 in a common year. - fn months_for_every_year(year: i32, cache: &()) -> u8 { - if Self::is_leap_year(year) { + fn months_for_every_year(year: i32, data: &Self::PrecomputedData) -> u8 { + if Self::is_leap_year(year, data) { 13 } else { 12 @@ -482,7 +482,7 @@ impl CalendarArithmetic for C { } /// Returns true if the given year is a leap year, and false if not. - fn is_leap_year(year: i32, cache: &()) -> bool { + fn is_leap_year(year: i32, _data: &Self::PrecomputedData) -> bool { if let Some(data) = C::get_compiled_data_for_year(year) { data.leap_month.is_some() } else { @@ -494,7 +494,7 @@ impl CalendarArithmetic for C { /// The last month in a year will always be 12 in a common year or 13 in a leap year. The day is /// determined by finding the day immediately before the next new year and calculating the number /// of days since the last new moon (beginning of the last month in the year). - fn last_month_day_in_year(year: i32, cache: &()) -> (u8, u8) { + fn last_month_day_in_year(year: i32, _data: &Self::PrecomputedData) -> (u8, u8) { if let Some(data) = C::get_compiled_data_for_year(year) { if data.leap_month.is_some() { (13, data.days_in_month(13)) @@ -506,7 +506,7 @@ impl CalendarArithmetic for C { } } - fn days_in_provided_year(year: i32, cache: &()) -> u16 { + fn days_in_provided_year(year: i32, _data: &Self::PrecomputedData) -> u16 { if let Some(data) = C::get_compiled_data_for_year(year) { data.last_day_of_month(13) } else { diff --git a/components/calendar/src/coptic.rs b/components/calendar/src/coptic.rs index 74ae5fd9026..b950731cbd6 100644 --- a/components/calendar/src/coptic.rs +++ b/components/calendar/src/coptic.rs @@ -66,11 +66,12 @@ pub struct Coptic; pub struct CopticDateInner(pub(crate) ArithmeticDate); impl CalendarArithmetic for Coptic { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { if (1..=12).contains(&month) { 30 } else if month == 13 { - if Self::is_leap_year(year) { + if Self::is_leap_year(year, &()) { 6 } else { 5 @@ -80,24 +81,24 @@ impl CalendarArithmetic for Coptic { } } - fn months_for_every_year(_: i32) -> u8 { + fn months_for_every_year(_: i32, _data: &()) -> u8 { 13 } - fn is_leap_year(year: i32) -> bool { + fn is_leap_year(year: i32, _data: &()) -> bool { year % 4 == 3 } - fn last_month_day_in_year(year: i32) -> (u8, u8) { - if Self::is_leap_year(year) { + fn last_month_day_in_year(year: i32, _data: &()) -> (u8, u8) { + if Self::is_leap_year(year, &()) { (13, 6) } else { (13, 5) } } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 366 } else { 365 @@ -177,7 +178,7 @@ impl Calendar for Coptic { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -225,7 +226,7 @@ impl Coptic { } fn days_in_year_direct(year: i32) -> u16 { - if Coptic::is_leap_year(year) { + if Coptic::is_leap_year(year, &()) { 366 } else { 365 diff --git a/components/calendar/src/dangi.rs b/components/calendar/src/dangi.rs index c504bab27a7..caa9e9be9d5 100644 --- a/components/calendar/src/dangi.rs +++ b/components/calendar/src/dangi.rs @@ -207,7 +207,7 @@ impl Calendar for Dangi { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0 .0.year) + Self::is_leap_year(date.0 .0.year, &()) } fn month(&self, date: &Self::DateInner) -> crate::types::FormattableMonth { @@ -282,7 +282,7 @@ impl Calendar for Dangi { day_of_year: date.0 .0.day_of_year(), days_in_year: date.0.days_in_year_inner(), prev_year: Self::format_dangi_year(prev_year, None), - days_in_prev_year: Self::days_in_provided_year(prev_year), + days_in_prev_year: Self::days_in_provided_year(prev_year, &()), next_year: Self::format_dangi_year(next_year, None), } } diff --git a/components/calendar/src/ethiopian.rs b/components/calendar/src/ethiopian.rs index 972a07dd748..697f66dd4ee 100644 --- a/components/calendar/src/ethiopian.rs +++ b/components/calendar/src/ethiopian.rs @@ -86,11 +86,12 @@ pub struct Ethiopian(pub(crate) bool); pub struct EthiopianDateInner(ArithmeticDate); impl CalendarArithmetic for Ethiopian { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { if (1..=12).contains(&month) { 30 } else if month == 13 { - if Self::is_leap_year(year) { + if Self::is_leap_year(year, &()) { 6 } else { 5 @@ -100,24 +101,24 @@ impl CalendarArithmetic for Ethiopian { } } - fn months_for_every_year(_: i32) -> u8 { + fn months_for_every_year(_: i32, _data: &()) -> u8 { 13 } - fn is_leap_year(year: i32) -> bool { + fn is_leap_year(year: i32, _data: &()) -> bool { year % 4 == 3 } - fn last_month_day_in_year(year: i32) -> (u8, u8) { - if Self::is_leap_year(year) { + fn last_month_day_in_year(year: i32, _data: &()) -> (u8, u8) { + if Self::is_leap_year(year, &()) { (13, 6) } else { (13, 5) } } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 366 } else { 365 @@ -199,7 +200,7 @@ impl Calendar for Ethiopian { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -277,7 +278,7 @@ impl Ethiopian { } fn days_in_year_direct(year: i32) -> u16 { - if Ethiopian::is_leap_year(year) { + if Ethiopian::is_leap_year(year, &()) { 366 } else { 365 diff --git a/components/calendar/src/hebrew.rs b/components/calendar/src/hebrew.rs index 62a4ed6b4cc..082e7703063 100644 --- a/components/calendar/src/hebrew.rs +++ b/components/calendar/src/hebrew.rs @@ -90,24 +90,25 @@ impl Hebrew { // HEBREW CALENDAR impl CalendarArithmetic for Hebrew { - fn month_days(civil_year: i32, civil_month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(civil_year: i32, civil_month: u8, _data: &()) -> u8 { Self::last_day_of_civil_hebrew_month(civil_year, civil_month) } - fn months_for_every_year(civil_year: i32) -> u8 { + fn months_for_every_year(civil_year: i32, _data: &()) -> u8 { Self::last_month_of_civil_hebrew_year(civil_year) } - fn days_in_provided_year(civil_year: i32) -> u16 { + fn days_in_provided_year(civil_year: i32, _data: &()) -> u16 { BookHebrew::days_in_book_hebrew_year(civil_year) // number of days don't change between BookHebrew and Civil Hebrew } - fn is_leap_year(civil_year: i32) -> bool { + fn is_leap_year(civil_year: i32, _data: &()) -> bool { // civil and book years are the same BookHebrew::is_hebrew_leap_year(civil_year) } - fn last_month_day_in_year(civil_year: i32) -> (u8, u8) { + fn last_month_day_in_year(civil_year: i32, _data: &()) -> (u8, u8) { let civil_month = Self::last_month_of_civil_hebrew_year(civil_year); let civil_day = Self::last_day_of_civil_hebrew_month(civil_year, civil_month); @@ -125,7 +126,7 @@ impl Calendar for Hebrew { month_code: types::MonthCode, day: u8, ) -> Result { - let is_leap_year = Self::is_leap_year(year); + let is_leap_year = Self::is_leap_year(year, &()); let year = if era.0 == tinystr!(16, "hebrew") || era.0 == tinystr!(16, "am") { year } else { @@ -229,12 +230,12 @@ impl Calendar for Hebrew { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> FormattableMonth { let mut ordinal = date.0.month; - let is_leap_year = Self::is_leap_year(date.0.year); + let is_leap_year = Self::is_leap_year(date.0.year, &()); if is_leap_year { if ordinal == 6 { @@ -287,7 +288,7 @@ impl Calendar for Hebrew { day_of_year: date.0.day_of_year(), days_in_year: date.0.days_in_year(), prev_year: Self::year_as_hebrew(prev_year), - days_in_prev_year: Self::days_in_provided_year(prev_year), + days_in_prev_year: Self::days_in_provided_year(prev_year, &()), next_year: Self::year_as_hebrew(next_year), } } @@ -311,7 +312,7 @@ impl Hebrew { } fn last_month_of_civil_hebrew_year(civil_year: i32) -> u8 { - if Self::is_leap_year(civil_year) { + if Self::is_leap_year(civil_year, &()) { 13 // there are 13 months in a leap year } else { 12 diff --git a/components/calendar/src/indian.rs b/components/calendar/src/indian.rs index 663f40973f3..25e9f40e1f2 100644 --- a/components/calendar/src/indian.rs +++ b/components/calendar/src/indian.rs @@ -61,9 +61,10 @@ pub struct Indian; pub struct IndianDateInner(ArithmeticDate); impl CalendarArithmetic for Indian { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { if month == 1 { - if Self::is_leap_year(year) { + if Self::is_leap_year(year, &()) { 31 } else { 30 @@ -77,20 +78,20 @@ impl CalendarArithmetic for Indian { } } - fn months_for_every_year(_: i32) -> u8 { + fn months_for_every_year(_: i32, _data: &()) -> u8 { 12 } - fn is_leap_year(year: i32) -> bool { - Iso::is_leap_year(year + 78) + fn is_leap_year(year: i32, _data: &()) -> bool { + Iso::is_leap_year(year + 78, &()) } - fn last_month_day_in_year(_year: i32) -> (u8, u8) { + fn last_month_day_in_year(_year: i32, _data: &()) -> (u8, u8) { (12, 30) } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 366 } else { 365 @@ -129,7 +130,7 @@ impl Calendar for Indian { // This is in the previous Indian year let day_of_year_indian = if day_of_year_iso <= DAY_OFFSET { year -= 1; - let n_days = Self::days_in_provided_year(year); + let n_days = Self::days_in_provided_year(year, &()); // calculate day of year in previous year n_days + day_of_year_iso - DAY_OFFSET @@ -201,7 +202,7 @@ impl Calendar for Indian { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -250,7 +251,7 @@ impl Indian { } fn days_in_year_direct(year: i32) -> u16 { - if Indian::is_leap_year(year) { + if Indian::is_leap_year(year, &()) { 366 } else { 365 diff --git a/components/calendar/src/islamic.rs b/components/calendar/src/islamic.rs index d77c542457a..55b9d9d013d 100644 --- a/components/calendar/src/islamic.rs +++ b/components/calendar/src/islamic.rs @@ -146,27 +146,28 @@ impl IslamicTabular { pub struct IslamicDateInner(ArithmeticDate); impl CalendarArithmetic for IslamicObservational { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { calendrical_calculations::islamic::observational_islamic_month_days(year, month) } - fn months_for_every_year(_year: i32) -> u8 { + fn months_for_every_year(_year: i32, _data: &()) -> u8 { 12 } - fn days_in_provided_year(year: i32) -> u16 { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { (1..=12) - .map(|month| IslamicObservational::month_days(year, month) as u16) + .map(|month| IslamicObservational::month_days(year, month, &()) as u16) .sum() } // As an observational-lunar calendar, it does not have leap years. - fn is_leap_year(_year: i32) -> bool { + fn is_leap_year(_year: i32, _data: &()) -> bool { false } - fn last_month_day_in_year(year: i32) -> (u8, u8) { - let days = Self::month_days(year, 12); + fn last_month_day_in_year(year: i32, _data: &()) -> (u8, u8) { + let days = Self::month_days(year, 12, &()); (12, days) } @@ -240,7 +241,7 @@ impl Calendar for IslamicObservational { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -258,7 +259,7 @@ impl Calendar for IslamicObservational { day_of_year: date.0.day_of_year(), days_in_year: date.0.days_in_year(), prev_year: Self::year_as_islamic(prev_year), - days_in_prev_year: Self::days_in_provided_year(prev_year), + days_in_prev_year: Self::days_in_provided_year(prev_year, &()), next_year: Self::year_as_islamic(next_year), } } @@ -376,27 +377,28 @@ impl> DateTime { pub struct IslamicUmmAlQuraDateInner(ArithmeticDate); impl CalendarArithmetic for IslamicUmmAlQura { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { calendrical_calculations::islamic::saudi_islamic_month_days(year, month) } - fn months_for_every_year(_year: i32) -> u8 { + fn months_for_every_year(_year: i32, _data: &()) -> u8 { 12 } - fn days_in_provided_year(year: i32) -> u16 { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { (1..=12) - .map(|month| IslamicUmmAlQura::month_days(year, month) as u16) + .map(|month| IslamicUmmAlQura::month_days(year, month, &()) as u16) .sum() } // As an observational-lunar calendar, it does not have leap years. - fn is_leap_year(_year: i32) -> bool { + fn is_leap_year(_year: i32, _data: &()) -> bool { false } - fn last_month_day_in_year(year: i32) -> (u8, u8) { - let days = Self::month_days(year, 12); + fn last_month_day_in_year(year: i32, _data: &()) -> (u8, u8) { + let days = Self::month_days(year, 12, &()); (12, days) } @@ -469,7 +471,7 @@ impl Calendar for IslamicUmmAlQura { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -487,7 +489,7 @@ impl Calendar for IslamicUmmAlQura { day_of_year: date.0.day_of_year(), days_in_year: date.0.days_in_year(), prev_year: Self::year_as_islamic(prev_year), - days_in_prev_year: Self::days_in_provided_year(prev_year), + days_in_prev_year: Self::days_in_provided_year(prev_year, &()), next_year: Self::year_as_islamic(next_year), } } @@ -604,34 +606,35 @@ impl IslamicUmmAlQura { pub struct IslamicCivilDateInner(ArithmeticDate); impl CalendarArithmetic for IslamicCivil { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { match month { 1 | 3 | 5 | 7 | 9 | 11 => 30, 2 | 4 | 6 | 8 | 10 => 29, - 12 if Self::is_leap_year(year) => 30, + 12 if Self::is_leap_year(year, &()) => 30, 12 => 29, _ => 0, } } - fn months_for_every_year(_year: i32) -> u8 { + fn months_for_every_year(_year: i32, _data: &()) -> u8 { 12 } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 355 } else { 354 } } - fn is_leap_year(year: i32) -> bool { + fn is_leap_year(year: i32, _data: &()) -> bool { (14 + 11 * year).rem_euclid(30) < 11 } - fn last_month_day_in_year(year: i32) -> (u8, u8) { - if Self::is_leap_year(year) { + fn last_month_day_in_year(year: i32, _data: &()) -> (u8, u8) { + if Self::is_leap_year(year, &()) { (12, 30) } else { (12, 29) @@ -713,7 +716,7 @@ impl Calendar for IslamicCivil { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -731,7 +734,7 @@ impl Calendar for IslamicCivil { day_of_year: date.0.day_of_year(), days_in_year: date.0.days_in_year(), prev_year: Self::year_as_islamic(prev_year), - days_in_prev_year: Self::days_in_provided_year(prev_year), + days_in_prev_year: Self::days_in_provided_year(prev_year, &()), next_year: Self::year_as_islamic(next_year), } } @@ -850,34 +853,35 @@ impl> DateTime { pub struct IslamicTabularDateInner(ArithmeticDate); impl CalendarArithmetic for IslamicTabular { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { match month { 1 | 3 | 5 | 7 | 9 | 11 => 30, 2 | 4 | 6 | 8 | 10 => 29, - 12 if Self::is_leap_year(year) => 30, + 12 if Self::is_leap_year(year, &()) => 30, 12 => 29, _ => 0, } } - fn months_for_every_year(_year: i32) -> u8 { + fn months_for_every_year(_year: i32, _data: &()) -> u8 { 12 } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 355 } else { 354 } } - fn is_leap_year(year: i32) -> bool { + fn is_leap_year(year: i32, _data: &()) -> bool { (14 + 11 * year).rem_euclid(30) < 11 } - fn last_month_day_in_year(year: i32) -> (u8, u8) { - if Self::is_leap_year(year) { + fn last_month_day_in_year(year: i32, _data: &()) -> (u8, u8) { + if Self::is_leap_year(year, &()) { (12, 30) } else { (12, 29) @@ -957,7 +961,7 @@ impl Calendar for IslamicTabular { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -975,7 +979,7 @@ impl Calendar for IslamicTabular { day_of_year: date.0.day_of_year(), days_in_year: date.0.days_in_year(), prev_year: Self::year_as_islamic(prev_year), - days_in_prev_year: Self::days_in_provided_year(prev_year), + days_in_prev_year: Self::days_in_provided_year(prev_year, &()), next_year: Self::year_as_islamic(next_year), } } diff --git a/components/calendar/src/iso.rs b/components/calendar/src/iso.rs index 24cb6ceaf88..aff5b6139ee 100644 --- a/components/calendar/src/iso.rs +++ b/components/calendar/src/iso.rs @@ -59,30 +59,31 @@ pub struct Iso; pub struct IsoDateInner(pub(crate) ArithmeticDate); impl CalendarArithmetic for Iso { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { match month { 4 | 6 | 9 | 11 => 30, - 2 if Self::is_leap_year(year) => 29, + 2 if Self::is_leap_year(year, &()) => 29, 2 => 28, 1 | 3 | 5 | 7 | 8 | 10 | 12 => 31, _ => 0, } } - fn months_for_every_year(_: i32) -> u8 { + fn months_for_every_year(_: i32, _data: &()) -> u8 { 12 } - fn is_leap_year(year: i32) -> bool { + fn is_leap_year(year: i32, _data: &()) -> bool { calendrical_calculations::iso::is_leap_year(year) } - fn last_month_day_in_year(_year: i32) -> (u8, u8) { + fn last_month_day_in_year(_year: i32, _data: &()) -> (u8, u8) { (12, 31) } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 366 } else { 365 @@ -143,7 +144,7 @@ impl Calendar for Iso { // Corresponding months from // https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Corresponding_months - let month_offset = if Self::is_leap_year(date.0.year) { + let month_offset = if Self::is_leap_year(date.0.year, &()) { match date.0.month { 10 => 0, 5 => 1, @@ -195,7 +196,7 @@ impl Calendar for Iso { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } /// The calendar-specific month represented by `date` @@ -363,14 +364,14 @@ impl Iso { fn days_in_month(year: i32, month: u8) -> u8 { match month { 4 | 6 | 9 | 11 => 30, - 2 if Self::is_leap_year(year) => 29, + 2 if Self::is_leap_year(year, &()) => 29, 2 => 28, _ => 31, } } pub(crate) fn days_in_year_direct(year: i32) -> u16 { - if Self::is_leap_year(year) { + if Self::is_leap_year(year, &()) { 366 } else { 365 @@ -421,7 +422,7 @@ impl Iso { let month_offset = [0, 1, -1, 0, 0, 1, 1, 2, 3, 3, 4, 4]; #[allow(clippy::indexing_slicing)] // date.0.month in 1..=12 let mut offset = month_offset[date.0.month as usize - 1]; - if Self::is_leap_year(date.0.year) && date.0.month > 2 { + if Self::is_leap_year(date.0.year, &()) && date.0.month > 2 { // Months after February in a leap year are offset by one less offset += 1; } diff --git a/components/calendar/src/julian.rs b/components/calendar/src/julian.rs index 8e72f3d5c1d..1427169440e 100644 --- a/components/calendar/src/julian.rs +++ b/components/calendar/src/julian.rs @@ -65,30 +65,31 @@ pub struct Julian; pub struct JulianDateInner(pub(crate) ArithmeticDate); impl CalendarArithmetic for Julian { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { match month { 4 | 6 | 9 | 11 => 30, - 2 if Self::is_leap_year(year) => 29, + 2 if Self::is_leap_year(year, &()) => 29, 2 => 28, 1 | 3 | 5 | 7 | 8 | 10 | 12 => 31, _ => 0, } } - fn months_for_every_year(_: i32) -> u8 { + fn months_for_every_year(_: i32, _data: &()) -> u8 { 12 } - fn is_leap_year(year: i32) -> bool { + fn is_leap_year(year: i32, _data: &()) -> bool { calendrical_calculations::julian::is_leap_year(year) } - fn last_month_day_in_year(_year: i32) -> (u8, u8) { + fn last_month_day_in_year(_year: i32, _data: &()) -> (u8, u8) { (12, 31) } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 366 } else { 365 @@ -170,7 +171,7 @@ impl Calendar for Julian { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } /// The calendar-specific month represented by `date` @@ -218,7 +219,7 @@ impl Julian { /// Convenience function so we can call days_in_year without /// needing to construct a full ArithmeticDate fn days_in_year_direct(year: i32) -> u16 { - if Julian::is_leap_year(year) { + if Julian::is_leap_year(year, &()) { 366 } else { 365 diff --git a/components/calendar/src/persian.rs b/components/calendar/src/persian.rs index 50d5444ad9f..2ba9b3487b2 100644 --- a/components/calendar/src/persian.rs +++ b/components/calendar/src/persian.rs @@ -64,21 +64,22 @@ pub struct Persian; pub struct PersianDateInner(ArithmeticDate); impl CalendarArithmetic for Persian { - fn month_days(year: i32, month: u8) -> u8 { + type PrecomputedData = (); + fn month_days(year: i32, month: u8, _data: &()) -> u8 { match month { 1..=6 => 31, 7..=11 => 30, - 12 if Self::is_leap_year(year) => 30, + 12 if Self::is_leap_year(year, &()) => 30, 12 => 29, _ => 0, } } - fn months_for_every_year(_: i32) -> u8 { + fn months_for_every_year(_: i32, _data: &()) -> u8 { 12 } // Lisp code reference: https://github.com/EdReingold/calendar-code2/blob/main/calendar.l#L4789 - fn is_leap_year(p_year: i32) -> bool { + fn is_leap_year(p_year: i32, _data: &()) -> bool { let mut p_year = p_year as i64; if 0 < p_year { p_year -= 474; @@ -90,16 +91,16 @@ impl CalendarArithmetic for Persian { ((year + 38) * 31).rem_euclid(128) < 31 } - fn days_in_provided_year(year: i32) -> u16 { - if Self::is_leap_year(year) { + fn days_in_provided_year(year: i32, _data: &()) -> u16 { + if Self::is_leap_year(year, &()) { 366 } else { 365 } } - fn last_month_day_in_year(year: i32) -> (u8, u8) { - if Self::is_leap_year(year) { + fn last_month_day_in_year(year: i32, _data: &()) -> (u8, u8) { + if Self::is_leap_year(year, &()) { (12, 30) } else { (12, 29) @@ -172,7 +173,7 @@ impl Calendar for Persian { } fn is_in_leap_year(&self, date: &Self::DateInner) -> bool { - Self::is_leap_year(date.0.year) + Self::is_leap_year(date.0.year, &()) } fn month(&self, date: &Self::DateInner) -> types::FormattableMonth { @@ -190,7 +191,7 @@ impl Calendar for Persian { day_of_year: date.0.day_of_year(), days_in_year: date.0.days_in_year(), prev_year: Persian::year_as_persian(prev_year), - days_in_prev_year: Persian::days_in_provided_year(prev_year), + days_in_prev_year: Persian::days_in_provided_year(prev_year, &()), next_year: Persian::year_as_persian(next_year), } } @@ -505,7 +506,7 @@ mod tests { let canonical_leap_year_cycle_start = 474; let canonical_leap_year_cycle_end = 3293; for year in canonical_leap_year_cycle_start..=canonical_leap_year_cycle_end { - let r = Persian::is_leap_year(year); + let r = Persian::is_leap_year(year, &()); if r { leap_year_results.push(r); }