Skip to content

Commit 3ce2ca7

Browse files
Allow different calendars to return different year-info types (#6439)
1 parent bbf2ee3 commit 3ce2ca7

File tree

38 files changed

+475
-447
lines changed

38 files changed

+475
-447
lines changed

components/calendar/README.md

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/calendar/benches/convert.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ fn bench_calendar<C: Clone + Calendar>(
1818
group.bench_function(name, |b| {
1919
b.iter(|| {
2020
let converted = black_box(iso).to_calendar(Ref(&calendar));
21-
let year = black_box(converted.year().era_year_or_related_iso());
22-
let month = black_box(converted.month().ordinal);
23-
let day = black_box(converted.day_of_month().0);
21+
let year = black_box(converted.year());
22+
let month = black_box(converted.month());
23+
let day = black_box(converted.day_of_month());
2424
black_box((converted, year, month, day))
2525
})
2626
});

components/calendar/benches/date.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ fn bench_date<A: AsCalendar>(date: &mut Date<A>) {
2121
));
2222

2323
// Retrieving vals
24-
let _ = black_box(date.year().era_year_or_related_iso());
25-
let _ = black_box(date.month().ordinal);
26-
let _ = black_box(date.day_of_month().0);
24+
let _ = black_box(date.year());
25+
let _ = black_box(date.month());
26+
let _ = black_box(date.day_of_month());
2727

2828
// Conversion to ISO.
2929
let _ = black_box(date.to_iso());

components/calendar/examples/iso_date_manipulations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn main() {
3232
let date = Date::try_new_iso(year, month, day).expect("date should parse");
3333
println!(
3434
"Year: {}, Month: {}, Day: {}",
35-
date.year().era_year_or_related_iso(),
35+
date.extended_year(),
3636
date.month().ordinal,
3737
date.day_of_month().0,
3838
);

components/calendar/src/any_calendar.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::cal::{
1212
Iso, Japanese, JapaneseExtended, Persian, Roc,
1313
};
1414
use crate::error::DateError;
15+
use crate::types::YearInfo;
1516
use crate::{types, AsCalendar, Calendar, Date, DateDuration, DateDurationUnit, Ref};
1617

1718
use crate::preferences::{CalendarAlgorithm, HijriCalendarAlgorithm};
@@ -219,6 +220,8 @@ macro_rules! match_cal {
219220

220221
impl Calendar for AnyCalendar {
221222
type DateInner = AnyDateInner;
223+
type Year = YearInfo;
224+
222225
fn from_codes(
223226
&self,
224227
era: Option<&str>,
@@ -465,9 +468,14 @@ impl Calendar for AnyCalendar {
465468
}
466469
}
467470

468-
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
469-
match_cal_and_date!(match (self, date): (c, d) => c.year(d))
471+
fn year_info(&self, date: &Self::DateInner) -> types::YearInfo {
472+
match_cal_and_date!(match (self, date): (c, d) => c.year_info(d).into())
473+
}
474+
475+
fn extended_year(&self, date: &Self::DateInner) -> i32 {
476+
match_cal_and_date!(match (self, date): (c, d) => c.extended_year(d))
470477
}
478+
471479
/// The calendar-specific check if `date` is in a leap year
472480
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
473481
match_cal_and_date!(match (self, date): (c, d) => c.is_in_leap_year(d))

components/calendar/src/cal/buddhist.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! .expect("Failed to initialize ISO Date instance.");
1212
//! let date_buddhist = Date::new_from_iso(date_iso, Buddhist);
1313
//!
14-
//! assert_eq!(date_buddhist.year().era_year_or_related_iso(), 2513);
14+
//! assert_eq!(date_buddhist.era_year().year, 2513);
1515
//! assert_eq!(date_buddhist.month().ordinal, 1);
1616
//! assert_eq!(date_buddhist.day_of_month().0, 2);
1717
//! ```
@@ -52,6 +52,7 @@ pub struct Buddhist;
5252

5353
impl Calendar for Buddhist {
5454
type DateInner = IsoDateInner;
55+
type Year = types::EraYear;
5556

5657
fn from_codes(
5758
&self,
@@ -115,17 +116,17 @@ impl Calendar for Buddhist {
115116
}
116117

117118
/// The calendar-specific year represented by `date`
118-
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
119-
let buddhist_year = date.0.year + BUDDHIST_ERA_OFFSET;
120-
types::YearInfo::new(
121-
buddhist_year,
122-
types::EraYear {
123-
standard_era: tinystr!(16, "be").into(),
124-
formatting_era: types::FormattingEra::Index(0, tinystr!(16, "BE")),
125-
era_year: buddhist_year,
126-
ambiguity: types::YearAmbiguity::CenturyRequired,
127-
},
128-
)
119+
fn year_info(&self, date: &Self::DateInner) -> Self::Year {
120+
types::EraYear {
121+
standard_era: tinystr!(16, "be").into(),
122+
formatting_era: types::FormattingEra::Index(0, tinystr!(16, "BE")),
123+
year: self.extended_year(date),
124+
ambiguity: types::YearAmbiguity::CenturyRequired,
125+
}
126+
}
127+
128+
fn extended_year(&self, date: &Self::DateInner) -> i32 {
129+
Iso.extended_year(date) + BUDDHIST_ERA_OFFSET
129130
}
130131

131132
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
@@ -167,7 +168,7 @@ impl Date<Buddhist> {
167168
/// let date_buddhist = Date::try_new_buddhist(1970, 1, 2)
168169
/// .expect("Failed to initialize Buddhist Date instance.");
169170
///
170-
/// assert_eq!(date_buddhist.year().era_year_or_related_iso(), 1970);
171+
/// assert_eq!(date_buddhist.era_year().year, 1970);
171172
/// assert_eq!(date_buddhist.month().ordinal, 1);
172173
/// assert_eq!(date_buddhist.day_of_month().0, 2);
173174
/// ```
@@ -280,7 +281,7 @@ mod test {
280281
let iso1 = Date::try_new_iso(iso_year, iso_month, iso_day).unwrap();
281282
let buddhist1 = iso1.to_calendar(Buddhist);
282283
assert_eq!(
283-
buddhist1.year().era_year_or_related_iso(),
284+
buddhist1.era_year().year,
284285
buddhist_year,
285286
"Iso -> Buddhist year check failed for case: {case:?}"
286287
);
@@ -299,7 +300,7 @@ mod test {
299300
Date::try_new_buddhist(buddhist_year, buddhist_month, buddhist_day).unwrap();
300301
let iso2 = buddhist2.to_calendar(Iso);
301302
assert_eq!(
302-
iso2.year().era_year_or_related_iso(),
303+
iso2.era_year().year,
303304
iso_year,
304305
"Buddhist -> Iso year check failed for case: {case:?}"
305306
);

components/calendar/src/cal/chinese.rs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
//! let chinese_date = Date::try_new_chinese_with_calendar(2023, 6, 6, chinese)
1212
//! .expect("Failed to initialize Chinese Date instance.");
1313
//!
14-
//! assert_eq!(chinese_date.year().era_year_or_related_iso(), 2023);
15-
//! assert_eq!(chinese_date.year().cyclic().unwrap().get(), 40);
14+
//! assert_eq!(chinese_date.cyclic_year().related_iso, 2023);
15+
//! assert_eq!(chinese_date.cyclic_year().year.get(), 40);
1616
//! assert_eq!(chinese_date.month().ordinal, 6);
1717
//! assert_eq!(chinese_date.day_of_month().0, 6);
1818
//! ```
@@ -159,6 +159,7 @@ impl Chinese {
159159

160160
impl Calendar for Chinese {
161161
type DateInner = ChineseDateInner;
162+
type Year = types::CyclicYear;
162163

163164
// Construct a date from era/month codes and fields
164165
fn from_codes(
@@ -242,15 +243,18 @@ impl Calendar for Chinese {
242243
Self::DEBUG_NAME
243244
}
244245

245-
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
246+
fn year_info(&self, date: &Self::DateInner) -> Self::Year {
246247
let year = date.0 .0.year;
247248
let cyclic = (year.related_iso - 4).rem_euclid(60) as u8;
248249
let cyclic = NonZeroU8::new(cyclic + 1).unwrap_or(NonZeroU8::MIN); // 1-indexed
249-
types::YearInfo::new_cyclic(
250-
chinese_based::Chinese::extended_from_iso(year.related_iso),
251-
cyclic,
252-
year.related_iso,
253-
)
250+
types::CyclicYear {
251+
year: cyclic,
252+
related_iso: year.related_iso,
253+
}
254+
}
255+
256+
fn extended_year(&self, date: &Self::DateInner) -> i32 {
257+
chinese_based::Chinese::extended_from_iso(date.0 .0.year.related_iso)
254258
}
255259

256260
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
@@ -302,9 +306,8 @@ impl<A: AsCalendar<Calendar = Chinese>> Date<A> {
302306
/// Date::try_new_chinese_with_calendar(2023, 6, 11, chinese)
303307
/// .expect("Failed to initialize Chinese Date instance.");
304308
///
305-
/// assert_eq!(date_chinese.year().era_year_or_related_iso(), 2023);
306-
/// assert_eq!(date_chinese.year().cyclic().unwrap().get(), 40);
307-
/// assert_eq!(date_chinese.year().related_iso(), Some(2023));
309+
/// assert_eq!(date_chinese.cyclic_year().related_iso, 2023);
310+
/// assert_eq!(date_chinese.cyclic_year().year.get(), 40);
308311
/// assert_eq!(date_chinese.month().ordinal, 6);
309312
/// assert_eq!(date_chinese.day_of_month().0, 11);
310313
/// ```
@@ -460,7 +463,7 @@ mod test {
460463
let chinese = Date::from_rata_die(rata_die, chinese);
461464
assert_eq!(
462465
case.expected_year,
463-
chinese.year().extended_year,
466+
chinese.extended_year(),
464467
"[{calendar_type}] Chinese from RD failed, case: {case:?}"
465468
);
466469
assert_eq!(
@@ -560,12 +563,12 @@ mod test {
560563
|chinese, _calendar_type| {
561564
let chinese = iso.to_calendar(chinese);
562565

563-
assert_eq!(chinese.year().era_year_or_related_iso(), -2636);
566+
assert_eq!(chinese.cyclic_year().related_iso, -2636);
564567
assert_eq!(chinese.month().ordinal, 1);
565568
assert_eq!(chinese.month().standard_code.0, "M01");
566569
assert_eq!(chinese.day_of_month().0, 1);
567-
assert_eq!(chinese.year().cyclic().unwrap().get(), 1);
568-
assert_eq!(chinese.year().related_iso(), Some(-2636));
570+
assert_eq!(chinese.cyclic_year().year.get(), 1);
571+
assert_eq!(chinese.cyclic_year().related_iso, -2636);
569572
},
570573
)
571574
}
@@ -613,7 +616,7 @@ mod test {
613616
let chinese = iso.to_calendar(chinese);
614617
assert_eq!(
615618
case.expected_year,
616-
chinese.year().era_year_or_related_iso(),
619+
chinese.cyclic_year().related_iso,
617620
"[{calendar_type}] ISO to Chinese failed for case: {case:?}"
618621
);
619622
assert_eq!(
@@ -1010,18 +1013,17 @@ mod test {
10101013
&chinese_cached,
10111014
|chinese, calendar_type| {
10121015
let chinese = iso.to_calendar(chinese);
1013-
let chinese_rel_iso = chinese.year().related_iso();
1014-
let chinese_cyclic = chinese.year().cyclic();
1016+
let chinese_rel_iso = chinese.cyclic_year().related_iso;
1017+
let chinese_cyclic = chinese.cyclic_year().year;
10151018
let chinese_month = chinese.month().ordinal;
10161019
let chinese_day = chinese.day_of_month().0;
10171020

10181021
assert_eq!(
1019-
chinese_rel_iso,
1020-
Some(case.expected_rel_iso),
1022+
chinese_rel_iso, case.expected_rel_iso,
10211023
"[{calendar_type}] Related ISO failed for test case: {case:?}"
10221024
);
10231025
assert_eq!(
1024-
chinese_cyclic.unwrap().get(),
1026+
chinese_cyclic.get(),
10251027
case.expected_cyclic,
10261028
"[{calendar_type}] Cyclic year failed for test case: {case:?}"
10271029
);

components/calendar/src/cal/coptic.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! .expect("Failed to initialize ISO Date instance.");
1212
//! let date_coptic = Date::new_from_iso(date_iso, Coptic);
1313
//!
14-
//! assert_eq!(date_coptic.year().era_year_or_related_iso(), 1686);
14+
//! assert_eq!(date_coptic.era_year().year, 1686);
1515
//! assert_eq!(date_coptic.month().ordinal, 4);
1616
//! assert_eq!(date_coptic.day_of_month().0, 24);
1717
//! ```
@@ -94,6 +94,7 @@ impl CalendarArithmetic for Coptic {
9494

9595
impl Calendar for Coptic {
9696
type DateInner = CopticDateInner;
97+
type Year = types::EraYear;
9798
fn from_codes(
9899
&self,
99100
era: Option<&str>,
@@ -160,31 +161,29 @@ impl Calendar for Coptic {
160161
date1.0.until(date2.0, _largest_unit, _smallest_unit)
161162
}
162163

163-
fn year(&self, date: &Self::DateInner) -> types::YearInfo {
164-
let year = date.0.year;
164+
fn year_info(&self, date: &Self::DateInner) -> Self::Year {
165+
let year = self.extended_year(date);
165166
if year > 0 {
166-
types::YearInfo::new(
167+
types::EraYear {
168+
standard_era: tinystr!(16, "am").into(),
169+
formatting_era: types::FormattingEra::Index(1, tinystr!(16, "AM")),
167170
year,
168-
types::EraYear {
169-
standard_era: tinystr!(16, "am").into(),
170-
formatting_era: types::FormattingEra::Index(1, tinystr!(16, "AM")),
171-
era_year: year,
172-
ambiguity: types::YearAmbiguity::CenturyRequired,
173-
},
174-
)
171+
ambiguity: types::YearAmbiguity::CenturyRequired,
172+
}
175173
} else {
176-
types::YearInfo::new(
177-
year,
178-
types::EraYear {
179-
standard_era: tinystr!(16, "bd").into(),
180-
formatting_era: types::FormattingEra::Index(0, tinystr!(16, "BD")),
181-
era_year: 1 - year,
182-
ambiguity: types::YearAmbiguity::EraAndCenturyRequired,
183-
},
184-
)
174+
types::EraYear {
175+
standard_era: tinystr!(16, "bd").into(),
176+
formatting_era: types::FormattingEra::Index(0, tinystr!(16, "BD")),
177+
year: 1 - year,
178+
ambiguity: types::YearAmbiguity::EraAndCenturyRequired,
179+
}
185180
}
186181
}
187182

183+
fn extended_year(&self, date: &Self::DateInner) -> i32 {
184+
date.0.extended_year()
185+
}
186+
188187
fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
189188
Self::provided_year_is_leap(date.0.year)
190189
}
@@ -221,7 +220,7 @@ impl Date<Coptic> {
221220
/// let date_coptic = Date::try_new_coptic(1686, 5, 6)
222221
/// .expect("Failed to initialize Coptic Date instance.");
223222
///
224-
/// assert_eq!(date_coptic.year().era_year_or_related_iso(), 1686);
223+
/// assert_eq!(date_coptic.era_year().year, 1686);
225224
/// assert_eq!(date_coptic.month().ordinal, 5);
226225
/// assert_eq!(date_coptic.day_of_month().0, 6);
227226
/// ```

0 commit comments

Comments
 (0)