1use crate::buddhist::Buddhist;
8use crate::chinese::Chinese;
9use crate::coptic::Coptic;
10use crate::dangi::Dangi;
11use crate::ethiopian::{Ethiopian, EthiopianEraStyle};
12use crate::gregorian::Gregorian;
13use crate::hebrew::Hebrew;
14use crate::indian::Indian;
15use crate::islamic::{IslamicCivil, IslamicObservational, IslamicTabular, IslamicUmmAlQura};
16use crate::iso::Iso;
17use crate::japanese::{Japanese, JapaneseExtended};
18use crate::persian::Persian;
19use crate::roc::Roc;
20use crate::{
21 types, AsCalendar, Calendar, CalendarError, Date, DateDuration, DateDurationUnit, DateTime, Ref,
22};
23
24use icu_locid::extensions::unicode::{key, value, Value};
25use icu_locid::subtags::language;
26use icu_locid::Locale;
27use icu_provider::prelude::*;
28
29use core::fmt;
30
31#[derive(Debug)]
75#[non_exhaustive]
76pub enum AnyCalendar {
77 Buddhist(Buddhist),
79 Chinese(Chinese),
81 Coptic(Coptic),
83 Dangi(Dangi),
85 Ethiopian(Ethiopian),
87 Gregorian(Gregorian),
89 Hebrew(Hebrew),
91 Indian(Indian),
93 IslamicCivil(IslamicCivil),
95 IslamicObservational(IslamicObservational),
97 IslamicTabular(IslamicTabular),
99 IslamicUmmAlQura(IslamicUmmAlQura),
101 Iso(Iso),
103 Japanese(Japanese),
105 JapaneseExtended(JapaneseExtended),
107 Persian(Persian),
109 Roc(Roc),
111}
112
113#[derive(Clone, PartialEq, Eq, Debug)]
116#[non_exhaustive]
117pub enum AnyDateInner {
118 Buddhist(<Buddhist as Calendar>::DateInner),
120 Chinese(<Chinese as Calendar>::DateInner),
122 Coptic(<Coptic as Calendar>::DateInner),
124 Dangi(<Dangi as Calendar>::DateInner),
126 Ethiopian(<Ethiopian as Calendar>::DateInner),
128 Gregorian(<Gregorian as Calendar>::DateInner),
130 Hebrew(<Hebrew as Calendar>::DateInner),
132 Indian(<Indian as Calendar>::DateInner),
134 IslamicCivil(<IslamicCivil as Calendar>::DateInner),
136 IslamicObservational(<IslamicObservational as Calendar>::DateInner),
138 IslamicTabular(<IslamicTabular as Calendar>::DateInner),
140 IslamicUmmAlQura(<IslamicUmmAlQura as Calendar>::DateInner),
142 Iso(<Iso as Calendar>::DateInner),
144 Japanese(<Japanese as Calendar>::DateInner),
146 JapaneseExtended(<JapaneseExtended as Calendar>::DateInner),
148 Persian(<Persian as Calendar>::DateInner),
150 Roc(<Roc as Calendar>::DateInner),
152}
153
154macro_rules! match_cal_and_date {
155 (match ($cal:ident, $date:ident): ($cal_matched:ident, $date_matched:ident) => $e:expr) => {
156 match ($cal, $date) {
157 (&Self::Buddhist(ref $cal_matched), &AnyDateInner::Buddhist(ref $date_matched)) => $e,
158 (&Self::Chinese(ref $cal_matched), &AnyDateInner::Chinese(ref $date_matched)) => $e,
159 (&Self::Coptic(ref $cal_matched), &AnyDateInner::Coptic(ref $date_matched)) => $e,
160 (&Self::Dangi(ref $cal_matched), &AnyDateInner::Dangi(ref $date_matched)) => $e,
161 (&Self::Ethiopian(ref $cal_matched), &AnyDateInner::Ethiopian(ref $date_matched)) => $e,
162 (&Self::Gregorian(ref $cal_matched), &AnyDateInner::Gregorian(ref $date_matched)) => $e,
163 (&Self::Hebrew(ref $cal_matched), &AnyDateInner::Hebrew(ref $date_matched)) => $e,
164 (&Self::Indian(ref $cal_matched), &AnyDateInner::Indian(ref $date_matched)) => $e,
165 (
166 &Self::IslamicCivil(ref $cal_matched),
167 &AnyDateInner::IslamicCivil(ref $date_matched),
168 ) => $e,
169 (
170 &Self::IslamicObservational(ref $cal_matched),
171 &AnyDateInner::IslamicObservational(ref $date_matched),
172 ) => $e,
173 (
174 &Self::IslamicTabular(ref $cal_matched),
175 &AnyDateInner::IslamicTabular(ref $date_matched),
176 ) => $e,
177 (
178 &Self::IslamicUmmAlQura(ref $cal_matched),
179 &AnyDateInner::IslamicUmmAlQura(ref $date_matched),
180 ) => $e,
181 (&Self::Iso(ref $cal_matched), &AnyDateInner::Iso(ref $date_matched)) => $e,
182 (&Self::Japanese(ref $cal_matched), &AnyDateInner::Japanese(ref $date_matched)) => $e,
183 (
184 &Self::JapaneseExtended(ref $cal_matched),
185 &AnyDateInner::JapaneseExtended(ref $date_matched),
186 ) => $e,
187 (&Self::Persian(ref $cal_matched), &AnyDateInner::Persian(ref $date_matched)) => $e,
188 (&Self::Roc(ref $cal_matched), &AnyDateInner::Roc(ref $date_matched)) => $e,
189 _ => panic!(
190 "Found AnyCalendar with mixed calendar type {:?} and date type {:?}!",
191 $cal.kind().debug_name(),
192 $date.kind().debug_name()
193 ),
194 }
195 };
196}
197
198impl Calendar for AnyCalendar {
199 type DateInner = AnyDateInner;
200 fn date_from_codes(
201 &self,
202 era: types::Era,
203 year: i32,
204 month_code: types::MonthCode,
205 day: u8,
206 ) -> Result<Self::DateInner, CalendarError> {
207 let ret = match *self {
208 Self::Buddhist(ref c) => {
209 AnyDateInner::Buddhist(c.date_from_codes(era, year, month_code, day)?)
210 }
211 Self::Chinese(ref c) => {
212 AnyDateInner::Chinese(c.date_from_codes(era, year, month_code, day)?)
213 }
214 Self::Coptic(ref c) => {
215 AnyDateInner::Coptic(c.date_from_codes(era, year, month_code, day)?)
216 }
217 Self::Dangi(ref c) => {
218 AnyDateInner::Dangi(c.date_from_codes(era, year, month_code, day)?)
219 }
220 Self::Ethiopian(ref c) => {
221 AnyDateInner::Ethiopian(c.date_from_codes(era, year, month_code, day)?)
222 }
223 Self::Gregorian(ref c) => {
224 AnyDateInner::Gregorian(c.date_from_codes(era, year, month_code, day)?)
225 }
226 Self::Hebrew(ref c) => {
227 AnyDateInner::Hebrew(c.date_from_codes(era, year, month_code, day)?)
228 }
229 Self::Indian(ref c) => {
230 AnyDateInner::Indian(c.date_from_codes(era, year, month_code, day)?)
231 }
232 Self::IslamicCivil(ref c) => {
233 AnyDateInner::IslamicCivil(c.date_from_codes(era, year, month_code, day)?)
234 }
235 Self::IslamicObservational(ref c) => {
236 AnyDateInner::IslamicObservational(c.date_from_codes(era, year, month_code, day)?)
237 }
238 Self::IslamicTabular(ref c) => {
239 AnyDateInner::IslamicTabular(c.date_from_codes(era, year, month_code, day)?)
240 }
241 Self::IslamicUmmAlQura(ref c) => {
242 AnyDateInner::IslamicUmmAlQura(c.date_from_codes(era, year, month_code, day)?)
243 }
244 Self::Iso(ref c) => AnyDateInner::Iso(c.date_from_codes(era, year, month_code, day)?),
245 Self::Japanese(ref c) => {
246 AnyDateInner::Japanese(c.date_from_codes(era, year, month_code, day)?)
247 }
248 Self::JapaneseExtended(ref c) => {
249 AnyDateInner::JapaneseExtended(c.date_from_codes(era, year, month_code, day)?)
250 }
251 Self::Persian(ref c) => {
252 AnyDateInner::Persian(c.date_from_codes(era, year, month_code, day)?)
253 }
254 Self::Roc(ref c) => AnyDateInner::Roc(c.date_from_codes(era, year, month_code, day)?),
255 };
256 Ok(ret)
257 }
258 fn date_from_iso(&self, iso: Date<Iso>) -> AnyDateInner {
259 match *self {
260 Self::Buddhist(ref c) => AnyDateInner::Buddhist(c.date_from_iso(iso)),
261 Self::Chinese(ref c) => AnyDateInner::Chinese(c.date_from_iso(iso)),
262 Self::Coptic(ref c) => AnyDateInner::Coptic(c.date_from_iso(iso)),
263 Self::Dangi(ref c) => AnyDateInner::Dangi(c.date_from_iso(iso)),
264 Self::Ethiopian(ref c) => AnyDateInner::Ethiopian(c.date_from_iso(iso)),
265 Self::Gregorian(ref c) => AnyDateInner::Gregorian(c.date_from_iso(iso)),
266 Self::Hebrew(ref c) => AnyDateInner::Hebrew(c.date_from_iso(iso)),
267 Self::Indian(ref c) => AnyDateInner::Indian(c.date_from_iso(iso)),
268 Self::IslamicCivil(ref c) => AnyDateInner::IslamicCivil(c.date_from_iso(iso)),
269 Self::IslamicObservational(ref c) => {
270 AnyDateInner::IslamicObservational(c.date_from_iso(iso))
271 }
272 Self::IslamicTabular(ref c) => AnyDateInner::IslamicTabular(c.date_from_iso(iso)),
273 Self::IslamicUmmAlQura(ref c) => AnyDateInner::IslamicUmmAlQura(c.date_from_iso(iso)),
274 Self::Iso(ref c) => AnyDateInner::Iso(c.date_from_iso(iso)),
275 Self::Japanese(ref c) => AnyDateInner::Japanese(c.date_from_iso(iso)),
276 Self::JapaneseExtended(ref c) => AnyDateInner::JapaneseExtended(c.date_from_iso(iso)),
277 Self::Persian(ref c) => AnyDateInner::Persian(c.date_from_iso(iso)),
278 Self::Roc(ref c) => AnyDateInner::Roc(c.date_from_iso(iso)),
279 }
280 }
281
282 fn date_to_iso(&self, date: &Self::DateInner) -> Date<Iso> {
283 match_cal_and_date!(match (self, date): (c, d) => c.date_to_iso(d))
284 }
285
286 fn months_in_year(&self, date: &Self::DateInner) -> u8 {
287 match_cal_and_date!(match (self, date): (c, d) => c.months_in_year(d))
288 }
289
290 fn days_in_year(&self, date: &Self::DateInner) -> u16 {
291 match_cal_and_date!(match (self, date): (c, d) => c.days_in_year(d))
292 }
293
294 fn days_in_month(&self, date: &Self::DateInner) -> u8 {
295 match_cal_and_date!(match (self, date): (c, d) => c.days_in_month(d))
296 }
297
298 fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
299 match (self, date) {
300 (Self::Buddhist(c), &mut AnyDateInner::Buddhist(ref mut d)) => {
301 c.offset_date(d, offset.cast_unit())
302 }
303 (Self::Chinese(c), &mut AnyDateInner::Chinese(ref mut d)) => {
304 c.offset_date(d, offset.cast_unit())
305 }
306 (Self::Coptic(c), &mut AnyDateInner::Coptic(ref mut d)) => {
307 c.offset_date(d, offset.cast_unit())
308 }
309 (Self::Dangi(c), &mut AnyDateInner::Dangi(ref mut d)) => {
310 c.offset_date(d, offset.cast_unit())
311 }
312 (Self::Ethiopian(c), &mut AnyDateInner::Ethiopian(ref mut d)) => {
313 c.offset_date(d, offset.cast_unit())
314 }
315 (Self::Gregorian(c), &mut AnyDateInner::Gregorian(ref mut d)) => {
316 c.offset_date(d, offset.cast_unit())
317 }
318 (Self::Hebrew(c), &mut AnyDateInner::Hebrew(ref mut d)) => {
319 c.offset_date(d, offset.cast_unit())
320 }
321 (Self::Indian(c), &mut AnyDateInner::Indian(ref mut d)) => {
322 c.offset_date(d, offset.cast_unit())
323 }
324 (Self::IslamicCivil(c), &mut AnyDateInner::IslamicCivil(ref mut d)) => {
325 c.offset_date(d, offset.cast_unit())
326 }
327 (Self::IslamicObservational(c), &mut AnyDateInner::IslamicObservational(ref mut d)) => {
328 c.offset_date(d, offset.cast_unit())
329 }
330 (Self::IslamicTabular(c), &mut AnyDateInner::IslamicTabular(ref mut d)) => {
331 c.offset_date(d, offset.cast_unit())
332 }
333 (Self::IslamicUmmAlQura(c), &mut AnyDateInner::IslamicUmmAlQura(ref mut d)) => {
334 c.offset_date(d, offset.cast_unit())
335 }
336 (Self::Iso(c), &mut AnyDateInner::Iso(ref mut d)) => {
337 c.offset_date(d, offset.cast_unit())
338 }
339 (Self::Japanese(c), &mut AnyDateInner::Japanese(ref mut d)) => {
340 c.offset_date(d, offset.cast_unit())
341 }
342 (Self::JapaneseExtended(c), &mut AnyDateInner::JapaneseExtended(ref mut d)) => {
343 c.offset_date(d, offset.cast_unit())
344 }
345 (Self::Persian(c), &mut AnyDateInner::Persian(ref mut d)) => {
346 c.offset_date(d, offset.cast_unit())
347 }
348 (Self::Roc(c), &mut AnyDateInner::Roc(ref mut d)) => {
349 c.offset_date(d, offset.cast_unit())
350 }
351 #[allow(clippy::panic)]
353 (_, d) => panic!(
354 "Found AnyCalendar with mixed calendar type {} and date type {}!",
355 self.kind().debug_name(),
356 d.kind().debug_name()
357 ),
358 }
359 }
360
361 fn until(
362 &self,
363 date1: &Self::DateInner,
364 date2: &Self::DateInner,
365 calendar2: &Self,
366 largest_unit: DateDurationUnit,
367 smallest_unit: DateDurationUnit,
368 ) -> DateDuration<Self> {
369 match (self, calendar2, date1, date2) {
370 (
371 Self::Buddhist(c1),
372 Self::Buddhist(c2),
373 AnyDateInner::Buddhist(d1),
374 AnyDateInner::Buddhist(d2),
375 ) => c1
376 .until(d1, d2, c2, largest_unit, smallest_unit)
377 .cast_unit(),
378 (
379 Self::Chinese(c1),
380 Self::Chinese(c2),
381 AnyDateInner::Chinese(d1),
382 AnyDateInner::Chinese(d2),
383 ) => c1
384 .until(d1, d2, c2, largest_unit, smallest_unit)
385 .cast_unit(),
386 (
387 Self::Coptic(c1),
388 Self::Coptic(c2),
389 AnyDateInner::Coptic(d1),
390 AnyDateInner::Coptic(d2),
391 ) => c1
392 .until(d1, d2, c2, largest_unit, smallest_unit)
393 .cast_unit(),
394 (
395 Self::Dangi(c1),
396 Self::Dangi(c2),
397 AnyDateInner::Dangi(d1),
398 AnyDateInner::Dangi(d2),
399 ) => c1
400 .until(d1, d2, c2, largest_unit, smallest_unit)
401 .cast_unit(),
402 (
403 Self::Ethiopian(c1),
404 Self::Ethiopian(c2),
405 AnyDateInner::Ethiopian(d1),
406 AnyDateInner::Ethiopian(d2),
407 ) => c1
408 .until(d1, d2, c2, largest_unit, smallest_unit)
409 .cast_unit(),
410 (
411 Self::Gregorian(c1),
412 Self::Gregorian(c2),
413 AnyDateInner::Gregorian(d1),
414 AnyDateInner::Gregorian(d2),
415 ) => c1
416 .until(d1, d2, c2, largest_unit, smallest_unit)
417 .cast_unit(),
418 (
419 Self::Hebrew(c1),
420 Self::Hebrew(c2),
421 AnyDateInner::Hebrew(d1),
422 AnyDateInner::Hebrew(d2),
423 ) => c1
424 .until(d1, d2, c2, largest_unit, smallest_unit)
425 .cast_unit(),
426 (
427 Self::Indian(c1),
428 Self::Indian(c2),
429 AnyDateInner::Indian(d1),
430 AnyDateInner::Indian(d2),
431 ) => c1
432 .until(d1, d2, c2, largest_unit, smallest_unit)
433 .cast_unit(),
434 (
435 Self::IslamicCivil(c1),
436 Self::IslamicCivil(c2),
437 AnyDateInner::IslamicCivil(d1),
438 AnyDateInner::IslamicCivil(d2),
439 ) => c1
440 .until(d1, d2, c2, largest_unit, smallest_unit)
441 .cast_unit(),
442 (
443 Self::IslamicObservational(c1),
444 Self::IslamicObservational(c2),
445 AnyDateInner::IslamicObservational(d1),
446 AnyDateInner::IslamicObservational(d2),
447 ) => c1
448 .until(d1, d2, c2, largest_unit, smallest_unit)
449 .cast_unit(),
450 (
451 Self::IslamicTabular(c1),
452 Self::IslamicTabular(c2),
453 AnyDateInner::IslamicTabular(d1),
454 AnyDateInner::IslamicTabular(d2),
455 ) => c1
456 .until(d1, d2, c2, largest_unit, smallest_unit)
457 .cast_unit(),
458 (
459 Self::IslamicUmmAlQura(c1),
460 Self::IslamicUmmAlQura(c2),
461 AnyDateInner::IslamicUmmAlQura(d1),
462 AnyDateInner::IslamicUmmAlQura(d2),
463 ) => c1
464 .until(d1, d2, c2, largest_unit, smallest_unit)
465 .cast_unit(),
466 (Self::Iso(c1), Self::Iso(c2), AnyDateInner::Iso(d1), AnyDateInner::Iso(d2)) => c1
467 .until(d1, d2, c2, largest_unit, smallest_unit)
468 .cast_unit(),
469 (
470 Self::Japanese(c1),
471 Self::Japanese(c2),
472 AnyDateInner::Japanese(d1),
473 AnyDateInner::Japanese(d2),
474 ) => c1
475 .until(d1, d2, c2, largest_unit, smallest_unit)
476 .cast_unit(),
477 (
478 Self::JapaneseExtended(c1),
479 Self::JapaneseExtended(c2),
480 AnyDateInner::JapaneseExtended(d1),
481 AnyDateInner::JapaneseExtended(d2),
482 ) => c1
483 .until(d1, d2, c2, largest_unit, smallest_unit)
484 .cast_unit(),
485 (
486 Self::Persian(c1),
487 Self::Persian(c2),
488 AnyDateInner::Persian(d1),
489 AnyDateInner::Persian(d2),
490 ) => c1
491 .until(d1, d2, c2, largest_unit, smallest_unit)
492 .cast_unit(),
493 (Self::Roc(c1), Self::Roc(c2), AnyDateInner::Roc(d1), AnyDateInner::Roc(d2)) => c1
494 .until(d1, d2, c2, largest_unit, smallest_unit)
495 .cast_unit(),
496 _ => {
497 let iso = calendar2.date_to_iso(date2);
499
500 match_cal_and_date!(match (self, date1):
501 (c1, d1) => {
502 let d2 = c1.date_from_iso(iso);
503 let until = c1.until(d1, &d2, c1, largest_unit, smallest_unit);
504 until.cast_unit::<AnyCalendar>()
505 }
506 )
507 }
508 }
509 }
510
511 fn year(&self, date: &Self::DateInner) -> types::FormattableYear {
513 match_cal_and_date!(match (self, date): (c, d) => c.year(d))
514 }
515
516 fn is_in_leap_year(&self, date: &Self::DateInner) -> bool {
518 match_cal_and_date!(match (self, date): (c, d) => c.is_in_leap_year(d))
519 }
520
521 fn month(&self, date: &Self::DateInner) -> types::FormattableMonth {
523 match_cal_and_date!(match (self, date): (c, d) => c.month(d))
524 }
525
526 fn day_of_month(&self, date: &Self::DateInner) -> types::DayOfMonth {
528 match_cal_and_date!(match (self, date): (c, d) => c.day_of_month(d))
529 }
530
531 fn day_of_year_info(&self, date: &Self::DateInner) -> types::DayOfYearInfo {
533 match_cal_and_date!(match (self, date): (c, d) => c.day_of_year_info(d))
534 }
535
536 fn debug_name(&self) -> &'static str {
537 match *self {
538 Self::Buddhist(_) => "AnyCalendar (Buddhist)",
539 Self::Chinese(_) => "AnyCalendar (Chinese)",
540 Self::Coptic(_) => "AnyCalendar (Coptic)",
541 Self::Dangi(_) => "AnyCalendar (Dangi)",
542 Self::Ethiopian(_) => "AnyCalendar (Ethiopian)",
543 Self::Gregorian(_) => "AnyCalendar (Gregorian)",
544 Self::Hebrew(_) => "AnyCalendar (Hebrew)",
545 Self::Indian(_) => "AnyCalendar (Indian)",
546 Self::IslamicCivil(_) => "AnyCalendar (Islamic, civil)",
547 Self::IslamicObservational(_) => "AnyCalendar (Islamic, observational)",
548 Self::IslamicTabular(_) => "AnyCalendar (Islamic, tabular)",
549 Self::IslamicUmmAlQura(_) => "AnyCalendar (Islamic, Umm al-Qura)",
550 Self::Iso(_) => "AnyCalendar (Iso)",
551 Self::Japanese(_) => "AnyCalendar (Japanese)",
552 Self::JapaneseExtended(_) => "AnyCalendar (Japanese, historical era data)",
553 Self::Persian(_) => "AnyCalendar (Persian)",
554 Self::Roc(_) => "AnyCalendar (Roc)",
555 }
556 }
557
558 fn any_calendar_kind(&self) -> Option<AnyCalendarKind> {
559 Some(self.kind())
560 }
561}
562
563impl AnyCalendar {
564 #[cfg(feature = "compiled_data")]
573 pub const fn new(kind: AnyCalendarKind) -> Self {
574 match kind {
575 AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
576 AnyCalendarKind::Chinese => AnyCalendar::Chinese(Chinese::new()),
577 AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
578 AnyCalendarKind::Dangi => AnyCalendar::Dangi(Dangi::new()),
579 AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
580 EthiopianEraStyle::AmeteMihret,
581 )),
582 AnyCalendarKind::EthiopianAmeteAlem => {
583 AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
584 }
585 AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
586 AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
587 AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
588 AnyCalendarKind::IslamicCivil => AnyCalendar::IslamicCivil(IslamicCivil),
589 AnyCalendarKind::IslamicObservational => {
590 AnyCalendar::IslamicObservational(IslamicObservational::new())
591 }
592 AnyCalendarKind::IslamicTabular => AnyCalendar::IslamicTabular(IslamicTabular),
593 AnyCalendarKind::IslamicUmmAlQura => {
594 AnyCalendar::IslamicUmmAlQura(IslamicUmmAlQura::new())
595 }
596 AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
597 AnyCalendarKind::Japanese => AnyCalendar::Japanese(Japanese::new()),
598 AnyCalendarKind::JapaneseExtended => {
599 AnyCalendar::JapaneseExtended(JapaneseExtended::new())
600 }
601 AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
602 AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
603 }
604 }
605
606 #[doc = icu_provider::gen_any_buffer_unstable_docs!(ANY, Self::new)]
607 pub fn try_new_with_any_provider<P>(
608 provider: &P,
609 kind: AnyCalendarKind,
610 ) -> Result<Self, CalendarError>
611 where
612 P: AnyProvider + ?Sized,
613 {
614 Ok(match kind {
615 AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
616 AnyCalendarKind::Chinese => {
617 AnyCalendar::Chinese(Chinese::try_new_with_any_provider(provider)?)
618 }
619 AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
620 AnyCalendarKind::Dangi => {
621 AnyCalendar::Dangi(Dangi::try_new_with_any_provider(provider)?)
622 }
623 AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
624 EthiopianEraStyle::AmeteMihret,
625 )),
626 AnyCalendarKind::EthiopianAmeteAlem => {
627 AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
628 }
629 AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
630 AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
631 AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
632 AnyCalendarKind::IslamicCivil => AnyCalendar::IslamicCivil(IslamicCivil),
633 AnyCalendarKind::IslamicObservational => AnyCalendar::IslamicObservational(
634 IslamicObservational::try_new_with_any_provider(provider)?,
635 ),
636 AnyCalendarKind::IslamicTabular => AnyCalendar::IslamicTabular(IslamicTabular),
637 AnyCalendarKind::IslamicUmmAlQura => AnyCalendar::IslamicUmmAlQura(
638 IslamicUmmAlQura::try_new_with_any_provider(provider)?,
639 ),
640 AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
641 AnyCalendarKind::Japanese => {
642 AnyCalendar::Japanese(Japanese::try_new_with_any_provider(provider)?)
643 }
644 AnyCalendarKind::JapaneseExtended => AnyCalendar::JapaneseExtended(
645 JapaneseExtended::try_new_with_any_provider(provider)?,
646 ),
647 AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
648 AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
649 })
650 }
651
652 #[cfg(feature = "serde")]
653 #[doc = icu_provider::gen_any_buffer_unstable_docs!(BUFFER, Self::new)]
654 pub fn try_new_with_buffer_provider<P>(
655 provider: &P,
656 kind: AnyCalendarKind,
657 ) -> Result<Self, CalendarError>
658 where
659 P: BufferProvider + ?Sized,
660 {
661 Ok(match kind {
662 AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
663 AnyCalendarKind::Chinese => {
664 AnyCalendar::Chinese(Chinese::try_new_with_buffer_provider(provider)?)
665 }
666 AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
667 AnyCalendarKind::Dangi => {
668 AnyCalendar::Dangi(Dangi::try_new_with_buffer_provider(provider)?)
669 }
670 AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
671 EthiopianEraStyle::AmeteMihret,
672 )),
673 AnyCalendarKind::EthiopianAmeteAlem => {
674 AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
675 }
676 AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
677 AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
678 AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
679 AnyCalendarKind::IslamicCivil => AnyCalendar::IslamicCivil(IslamicCivil),
680 AnyCalendarKind::IslamicObservational => AnyCalendar::IslamicObservational(
681 IslamicObservational::try_new_with_buffer_provider(provider)?,
682 ),
683 AnyCalendarKind::IslamicTabular => AnyCalendar::IslamicTabular(IslamicTabular),
684 AnyCalendarKind::IslamicUmmAlQura => AnyCalendar::IslamicUmmAlQura(
685 IslamicUmmAlQura::try_new_with_buffer_provider(provider)?,
686 ),
687 AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
688 AnyCalendarKind::Japanese => {
689 AnyCalendar::Japanese(Japanese::try_new_with_buffer_provider(provider)?)
690 }
691 AnyCalendarKind::JapaneseExtended => AnyCalendar::JapaneseExtended(
692 JapaneseExtended::try_new_with_buffer_provider(provider)?,
693 ),
694 AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
695 AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
696 })
697 }
698
699 #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::new)]
700 pub fn try_new_unstable<P>(provider: &P, kind: AnyCalendarKind) -> Result<Self, CalendarError>
701 where
702 P: DataProvider<crate::provider::JapaneseErasV1Marker>
703 + DataProvider<crate::provider::JapaneseExtendedErasV1Marker>
704 + DataProvider<crate::provider::ChineseCacheV1Marker>
705 + DataProvider<crate::provider::DangiCacheV1Marker>
706 + DataProvider<crate::provider::IslamicObservationalCacheV1Marker>
707 + DataProvider<crate::provider::IslamicUmmAlQuraCacheV1Marker>
708 + ?Sized,
709 {
710 Ok(match kind {
711 AnyCalendarKind::Buddhist => AnyCalendar::Buddhist(Buddhist),
712 AnyCalendarKind::Chinese => AnyCalendar::Chinese(Chinese::try_new_unstable(provider)?),
713 AnyCalendarKind::Coptic => AnyCalendar::Coptic(Coptic),
714 AnyCalendarKind::Dangi => AnyCalendar::Dangi(Dangi::try_new_unstable(provider)?),
715 AnyCalendarKind::Ethiopian => AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(
716 EthiopianEraStyle::AmeteMihret,
717 )),
718 AnyCalendarKind::EthiopianAmeteAlem => {
719 AnyCalendar::Ethiopian(Ethiopian::new_with_era_style(EthiopianEraStyle::AmeteAlem))
720 }
721 AnyCalendarKind::Gregorian => AnyCalendar::Gregorian(Gregorian),
722 AnyCalendarKind::Hebrew => AnyCalendar::Hebrew(Hebrew),
723 AnyCalendarKind::Indian => AnyCalendar::Indian(Indian),
724 AnyCalendarKind::IslamicCivil => AnyCalendar::IslamicCivil(IslamicCivil),
725 AnyCalendarKind::IslamicObservational => {
726 AnyCalendar::IslamicObservational(IslamicObservational::try_new_unstable(provider)?)
727 }
728 AnyCalendarKind::IslamicTabular => AnyCalendar::IslamicTabular(IslamicTabular),
729 AnyCalendarKind::IslamicUmmAlQura => {
730 AnyCalendar::IslamicUmmAlQura(IslamicUmmAlQura::try_new_unstable(provider)?)
731 }
732 AnyCalendarKind::Iso => AnyCalendar::Iso(Iso),
733 AnyCalendarKind::Japanese => {
734 AnyCalendar::Japanese(Japanese::try_new_unstable(provider)?)
735 }
736 AnyCalendarKind::JapaneseExtended => {
737 AnyCalendar::JapaneseExtended(JapaneseExtended::try_new_unstable(provider)?)
738 }
739 AnyCalendarKind::Persian => AnyCalendar::Persian(Persian),
740 AnyCalendarKind::Roc => AnyCalendar::Roc(Roc),
741 })
742 }
743
744 #[cfg(feature = "compiled_data")]
753 pub fn new_for_locale(locale: &DataLocale) -> Self {
754 let kind = AnyCalendarKind::from_data_locale_with_fallback(locale);
755 Self::new(kind)
756 }
757
758 icu_provider::gen_any_buffer_data_constructors!(
759 locale: include,
760 options: skip,
761 error: CalendarError,
762 #[cfg(skip)]
763 functions: [
764 new_for_locale,
765 try_new_for_locale_with_any_provider,
766 try_new_for_locale_with_buffer_provider,
767 try_new_for_locale_unstable,
768 Self,
769 ]
770 );
771
772 #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::new_for_locale)]
773 pub fn try_new_for_locale_unstable<P>(
774 provider: &P,
775 locale: &DataLocale,
776 ) -> Result<Self, CalendarError>
777 where
778 P: DataProvider<crate::provider::JapaneseErasV1Marker>
779 + DataProvider<crate::provider::JapaneseExtendedErasV1Marker>
780 + DataProvider<crate::provider::ChineseCacheV1Marker>
781 + DataProvider<crate::provider::DangiCacheV1Marker>
782 + DataProvider<crate::provider::IslamicObservationalCacheV1Marker>
783 + DataProvider<crate::provider::IslamicUmmAlQuraCacheV1Marker>
784 + ?Sized,
785 {
786 let kind = AnyCalendarKind::from_data_locale_with_fallback(locale);
787 Self::try_new_unstable(provider, kind)
788 }
789
790 pub fn kind(&self) -> AnyCalendarKind {
792 match *self {
793 Self::Buddhist(_) => AnyCalendarKind::Buddhist,
794 Self::Chinese(_) => AnyCalendarKind::Chinese,
795 Self::Coptic(_) => AnyCalendarKind::Coptic,
796 Self::Dangi(_) => AnyCalendarKind::Dangi,
797 #[allow(clippy::expect_used)] Self::Ethiopian(ref e) => e
799 .any_calendar_kind()
800 .expect("Ethiopian calendar known to have an AnyCalendarKind"),
801 Self::Gregorian(_) => AnyCalendarKind::Gregorian,
802 Self::Hebrew(_) => AnyCalendarKind::Hebrew,
803 Self::Indian(_) => AnyCalendarKind::Indian,
804 Self::IslamicCivil(_) => AnyCalendarKind::IslamicCivil,
805 Self::IslamicObservational(_) => AnyCalendarKind::IslamicObservational,
806 Self::IslamicTabular(_) => AnyCalendarKind::IslamicTabular,
807 Self::IslamicUmmAlQura(_) => AnyCalendarKind::IslamicUmmAlQura,
808 Self::Iso(_) => AnyCalendarKind::Iso,
809 Self::Japanese(_) => AnyCalendarKind::Japanese,
810 Self::JapaneseExtended(_) => AnyCalendarKind::JapaneseExtended,
811 Self::Persian(_) => AnyCalendarKind::Persian,
812 Self::Roc(_) => AnyCalendarKind::Roc,
813 }
814 }
815
816 pub fn convert_any_date<'a>(
819 &'a self,
820 date: &Date<impl AsCalendar<Calendar = AnyCalendar>>,
821 ) -> Date<Ref<'a, AnyCalendar>> {
822 if self.kind() != date.calendar.as_calendar().kind() {
823 Date::new_from_iso(date.to_iso(), Ref(self))
824 } else {
825 Date {
826 inner: date.inner.clone(),
827 calendar: Ref(self),
828 }
829 }
830 }
831
832 pub fn convert_any_datetime<'a>(
835 &'a self,
836 date: &DateTime<impl AsCalendar<Calendar = AnyCalendar>>,
837 ) -> DateTime<Ref<'a, AnyCalendar>> {
838 DateTime {
839 time: date.time,
840 date: self.convert_any_date(&date.date),
841 }
842 }
843}
844
845impl AnyDateInner {
846 fn kind(&self) -> AnyCalendarKind {
847 match *self {
848 AnyDateInner::Buddhist(_) => AnyCalendarKind::Buddhist,
849 AnyDateInner::Chinese(_) => AnyCalendarKind::Chinese,
850 AnyDateInner::Coptic(_) => AnyCalendarKind::Coptic,
851 AnyDateInner::Dangi(_) => AnyCalendarKind::Dangi,
852 AnyDateInner::Ethiopian(_) => AnyCalendarKind::Ethiopian,
853 AnyDateInner::Gregorian(_) => AnyCalendarKind::Gregorian,
854 AnyDateInner::Hebrew(_) => AnyCalendarKind::Hebrew,
855 AnyDateInner::Indian(_) => AnyCalendarKind::Indian,
856 AnyDateInner::IslamicCivil(_) => AnyCalendarKind::IslamicCivil,
857 AnyDateInner::IslamicObservational(_) => AnyCalendarKind::IslamicObservational,
858 AnyDateInner::IslamicTabular(_) => AnyCalendarKind::IslamicTabular,
859 AnyDateInner::IslamicUmmAlQura(_) => AnyCalendarKind::IslamicUmmAlQura,
860 AnyDateInner::Iso(_) => AnyCalendarKind::Iso,
861 AnyDateInner::Japanese(_) => AnyCalendarKind::Japanese,
862 AnyDateInner::JapaneseExtended(_) => AnyCalendarKind::JapaneseExtended,
863 AnyDateInner::Persian(_) => AnyCalendarKind::Persian,
864 AnyDateInner::Roc(_) => AnyCalendarKind::Roc,
865 }
866 }
867}
868
869#[non_exhaustive]
871#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
872pub enum AnyCalendarKind {
873 Buddhist,
875 Chinese,
877 Coptic,
879 Dangi,
881 Ethiopian,
883 EthiopianAmeteAlem,
885 Gregorian,
887 Hebrew,
889 Indian,
891 IslamicCivil,
893 IslamicObservational,
895 IslamicTabular,
897 IslamicUmmAlQura,
899 Iso,
901 Japanese,
903 JapaneseExtended,
905 Persian,
907 Roc,
909}
910
911impl AnyCalendarKind {
912 pub fn get_for_bcp47_string(x: &str) -> Option<Self> {
917 Self::get_for_bcp47_bytes(x.as_bytes())
918 }
919 pub fn get_for_bcp47_bytes(x: &[u8]) -> Option<Self> {
924 Some(match x {
925 b"buddhist" => AnyCalendarKind::Buddhist,
926 b"chinese" => AnyCalendarKind::Chinese,
927 b"coptic" => AnyCalendarKind::Coptic,
928 b"dangi" => AnyCalendarKind::Dangi,
929 b"ethioaa" => AnyCalendarKind::EthiopianAmeteAlem,
930 b"ethiopic" => AnyCalendarKind::Ethiopian,
931 b"gregory" => AnyCalendarKind::Gregorian,
932 b"hebrew" => AnyCalendarKind::Hebrew,
933 b"indian" => AnyCalendarKind::Indian,
934 b"islamic-civil" | b"islamicc" => AnyCalendarKind::IslamicCivil,
935 b"islamic-tbla" => AnyCalendarKind::IslamicTabular,
936 b"islamic-umalqura" => AnyCalendarKind::IslamicUmmAlQura,
937 b"islamic" => AnyCalendarKind::IslamicObservational,
938 b"iso" => AnyCalendarKind::Iso,
939 b"japanese" => AnyCalendarKind::Japanese,
940 b"japanext" => AnyCalendarKind::JapaneseExtended,
941 b"persian" => AnyCalendarKind::Persian,
942 b"roc" => AnyCalendarKind::Roc,
943 _ => {
944 DataError::custom("bcp47_bytes did not match any calendars").with_debug_context(x);
946 return None;
947 }
948 })
949 }
950 pub fn get_for_bcp47_value(x: &Value) -> Option<Self> {
955 match *x.as_tinystr_slice() {
956 [first] if first == "buddhist" => Some(AnyCalendarKind::Buddhist),
957 [first] if first == "chinese" => Some(AnyCalendarKind::Chinese),
958 [first] if first == "coptic" => Some(AnyCalendarKind::Coptic),
959 [first] if first == "dangi" => Some(AnyCalendarKind::Dangi),
960 [first] if first == "ethioaa" => Some(AnyCalendarKind::EthiopianAmeteAlem),
961 [first] if first == "ethiopic" => Some(AnyCalendarKind::Ethiopian),
962 [first] if first == "gregory" => Some(AnyCalendarKind::Gregorian),
963 [first] if first == "hebrew" => Some(AnyCalendarKind::Hebrew),
964 [first] if first == "indian" => Some(AnyCalendarKind::Indian),
965 [first] if first == "islamic" => Some(AnyCalendarKind::IslamicObservational),
966 [first] if first == "islamicc" => Some(AnyCalendarKind::IslamicCivil),
967 [first, second] if first == "islamic" && second == "civil" => {
968 Some(AnyCalendarKind::IslamicCivil)
969 }
970 [first, second] if first == "islamic" && second == "tbla" => {
971 Some(AnyCalendarKind::IslamicTabular)
972 }
973 [first, second] if first == "islamic" && second == "umalqura" => {
974 Some(AnyCalendarKind::IslamicUmmAlQura)
975 }
976 [first] if first == "iso" => Some(AnyCalendarKind::Iso),
977 [first] if first == "japanese" => Some(AnyCalendarKind::Japanese),
978 [first] if first == "japanext" => Some(AnyCalendarKind::JapaneseExtended),
979 [first] if first == "persian" => Some(AnyCalendarKind::Persian),
980 [first] if first == "roc" => Some(AnyCalendarKind::Roc),
981 _ => {
982 DataError::custom("bcp47_value did not match any calendars")
984 .with_display_context(x);
985 None
986 }
987 }
988 }
989
990 pub fn as_bcp47_string(self) -> &'static str {
992 match self {
993 AnyCalendarKind::Buddhist => "buddhist",
994 AnyCalendarKind::Chinese => "chinese",
995 AnyCalendarKind::Coptic => "coptic",
996 AnyCalendarKind::Dangi => "dangi",
997 AnyCalendarKind::Ethiopian => "ethiopic",
998 AnyCalendarKind::EthiopianAmeteAlem => "ethioaa",
999 AnyCalendarKind::Gregorian => "gregory",
1000 AnyCalendarKind::Hebrew => "hebrew",
1001 AnyCalendarKind::Indian => "indian",
1002 AnyCalendarKind::IslamicCivil => "islamic-civil",
1003 AnyCalendarKind::IslamicObservational => "islamic",
1004 AnyCalendarKind::IslamicTabular => "islamic-tbla",
1005 AnyCalendarKind::IslamicUmmAlQura => "islamic-umalqura",
1006 AnyCalendarKind::Iso => "iso",
1007 AnyCalendarKind::Japanese => "japanese",
1008 AnyCalendarKind::JapaneseExtended => "japanext",
1009 AnyCalendarKind::Persian => "persian",
1010 AnyCalendarKind::Roc => "roc",
1011 }
1012 }
1013
1014 #[allow(clippy::unwrap_used)] pub fn as_bcp47_value(self) -> Value {
1017 match self {
1018 AnyCalendarKind::Buddhist => value!("buddhist"),
1019 AnyCalendarKind::Chinese => value!("chinese"),
1020 AnyCalendarKind::Coptic => value!("coptic"),
1021 AnyCalendarKind::Dangi => value!("dangi"),
1022 AnyCalendarKind::Ethiopian => value!("ethiopic"),
1023 AnyCalendarKind::EthiopianAmeteAlem => value!("ethioaa"),
1024 AnyCalendarKind::Gregorian => value!("gregory"),
1025 AnyCalendarKind::Hebrew => value!("hebrew"),
1026 AnyCalendarKind::Indian => value!("indian"),
1027 AnyCalendarKind::IslamicCivil => Value::try_from_bytes(b"islamic-civil").unwrap(),
1028 AnyCalendarKind::IslamicObservational => value!("islamic"),
1029 AnyCalendarKind::IslamicTabular => Value::try_from_bytes(b"islamic-tbla").unwrap(),
1030 AnyCalendarKind::IslamicUmmAlQura => {
1031 Value::try_from_bytes(b"islamic-umalqura").unwrap()
1032 }
1033 AnyCalendarKind::Iso => value!("iso"),
1034 AnyCalendarKind::Japanese => value!("japanese"),
1035 AnyCalendarKind::JapaneseExtended => value!("japanext"),
1036 AnyCalendarKind::Persian => value!("persian"),
1037 AnyCalendarKind::Roc => value!("roc"),
1038 }
1039 }
1040
1041 fn debug_name(self) -> &'static str {
1042 match self {
1043 AnyCalendarKind::Buddhist => Buddhist.debug_name(),
1044 AnyCalendarKind::Chinese => Chinese::DEBUG_NAME,
1045 AnyCalendarKind::Coptic => Coptic.debug_name(),
1046 AnyCalendarKind::Dangi => Dangi::DEBUG_NAME,
1047 AnyCalendarKind::Ethiopian => Ethiopian(false).debug_name(),
1048 AnyCalendarKind::EthiopianAmeteAlem => Ethiopian(true).debug_name(),
1049 AnyCalendarKind::Gregorian => Gregorian.debug_name(),
1050 AnyCalendarKind::Hebrew => Hebrew.debug_name(),
1051 AnyCalendarKind::Indian => Indian.debug_name(),
1052 AnyCalendarKind::IslamicCivil => IslamicCivil.debug_name(),
1053 AnyCalendarKind::IslamicObservational => IslamicObservational::DEBUG_NAME,
1054 AnyCalendarKind::IslamicTabular => IslamicTabular.debug_name(),
1055 AnyCalendarKind::IslamicUmmAlQura => IslamicUmmAlQura::DEBUG_NAME,
1056 AnyCalendarKind::Iso => Iso.debug_name(),
1057 AnyCalendarKind::Japanese => Japanese::DEBUG_NAME,
1058 AnyCalendarKind::JapaneseExtended => JapaneseExtended::DEBUG_NAME,
1059 AnyCalendarKind::Persian => Persian.debug_name(),
1060 AnyCalendarKind::Roc => Roc.debug_name(),
1061 }
1062 }
1063
1064 pub fn get_for_locale(l: &Locale) -> Option<Self> {
1069 l.extensions
1070 .unicode
1071 .keywords
1072 .get(&key!("ca"))
1073 .and_then(Self::get_for_bcp47_value)
1074 }
1075
1076 fn get_for_data_locale(l: &DataLocale) -> Option<Self> {
1081 l.get_unicode_ext(&key!("ca"))
1082 .and_then(|v| Self::get_for_bcp47_value(&v))
1083 }
1084
1085 fn from_data_locale_with_fallback(l: &DataLocale) -> Self {
1088 if let Some(kind) = Self::get_for_data_locale(l) {
1089 kind
1090 } else {
1091 let lang = l.language();
1092 if lang == language!("th") {
1093 Self::Buddhist
1094 } else {
1100 Self::Gregorian
1101 }
1102 }
1103 }
1104}
1105
1106impl fmt::Display for AnyCalendarKind {
1107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1108 fmt::Debug::fmt(self, f)
1109 }
1110}
1111
1112impl<C: IntoAnyCalendar> From<C> for AnyCalendar {
1113 fn from(c: C) -> AnyCalendar {
1114 c.to_any()
1115 }
1116}
1117
1118pub trait IntoAnyCalendar: Calendar + Sized {
1120 fn to_any(self) -> AnyCalendar;
1124
1125 fn to_any_cloned(&self) -> AnyCalendar;
1129 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner;
1133}
1134
1135impl IntoAnyCalendar for Buddhist {
1136 fn to_any(self) -> AnyCalendar {
1137 AnyCalendar::Buddhist(Buddhist)
1138 }
1139 fn to_any_cloned(&self) -> AnyCalendar {
1140 AnyCalendar::Buddhist(Buddhist)
1141 }
1142 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1143 AnyDateInner::Buddhist(*d)
1144 }
1145}
1146
1147impl IntoAnyCalendar for Chinese {
1148 fn to_any(self) -> AnyCalendar {
1149 AnyCalendar::Chinese(self)
1150 }
1151 fn to_any_cloned(&self) -> AnyCalendar {
1152 AnyCalendar::Chinese(self.clone())
1153 }
1154 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1155 AnyDateInner::Chinese(*d)
1156 }
1157}
1158
1159impl IntoAnyCalendar for Coptic {
1160 fn to_any(self) -> AnyCalendar {
1161 AnyCalendar::Coptic(Coptic)
1162 }
1163 fn to_any_cloned(&self) -> AnyCalendar {
1164 AnyCalendar::Coptic(Coptic)
1165 }
1166 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1167 AnyDateInner::Coptic(*d)
1168 }
1169}
1170
1171impl IntoAnyCalendar for Dangi {
1172 fn to_any(self) -> AnyCalendar {
1173 AnyCalendar::Dangi(self)
1174 }
1175 fn to_any_cloned(&self) -> AnyCalendar {
1176 AnyCalendar::Dangi(self.clone())
1177 }
1178 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1179 AnyDateInner::Dangi(*d)
1180 }
1181}
1182
1183impl IntoAnyCalendar for Ethiopian {
1184 fn to_any(self) -> AnyCalendar {
1186 AnyCalendar::Ethiopian(self)
1187 }
1188 fn to_any_cloned(&self) -> AnyCalendar {
1189 AnyCalendar::Ethiopian(*self)
1190 }
1191 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1192 AnyDateInner::Ethiopian(*d)
1193 }
1194}
1195
1196impl IntoAnyCalendar for Gregorian {
1197 fn to_any(self) -> AnyCalendar {
1198 AnyCalendar::Gregorian(Gregorian)
1199 }
1200 fn to_any_cloned(&self) -> AnyCalendar {
1201 AnyCalendar::Gregorian(Gregorian)
1202 }
1203 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1204 AnyDateInner::Gregorian(*d)
1205 }
1206}
1207
1208impl IntoAnyCalendar for Hebrew {
1209 fn to_any(self) -> AnyCalendar {
1210 AnyCalendar::Hebrew(Hebrew)
1211 }
1212 fn to_any_cloned(&self) -> AnyCalendar {
1213 AnyCalendar::Hebrew(Hebrew)
1214 }
1215 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1216 AnyDateInner::Hebrew(*d)
1217 }
1218}
1219
1220impl IntoAnyCalendar for Indian {
1221 fn to_any(self) -> AnyCalendar {
1222 AnyCalendar::Indian(Indian)
1223 }
1224 fn to_any_cloned(&self) -> AnyCalendar {
1225 AnyCalendar::Indian(Indian)
1226 }
1227 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1228 AnyDateInner::Indian(*d)
1229 }
1230}
1231
1232impl IntoAnyCalendar for IslamicCivil {
1233 fn to_any(self) -> AnyCalendar {
1234 AnyCalendar::IslamicCivil(self)
1235 }
1236 fn to_any_cloned(&self) -> AnyCalendar {
1237 AnyCalendar::IslamicCivil(*self)
1238 }
1239 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1240 AnyDateInner::IslamicCivil(*d)
1241 }
1242}
1243
1244impl IntoAnyCalendar for IslamicObservational {
1245 fn to_any(self) -> AnyCalendar {
1246 AnyCalendar::IslamicObservational(self)
1247 }
1248 fn to_any_cloned(&self) -> AnyCalendar {
1249 AnyCalendar::IslamicObservational(self.clone())
1250 }
1251 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1252 AnyDateInner::IslamicObservational(*d)
1253 }
1254}
1255
1256impl IntoAnyCalendar for IslamicTabular {
1257 fn to_any(self) -> AnyCalendar {
1258 AnyCalendar::IslamicTabular(self)
1259 }
1260 fn to_any_cloned(&self) -> AnyCalendar {
1261 AnyCalendar::IslamicTabular(*self)
1262 }
1263 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1264 AnyDateInner::IslamicTabular(*d)
1265 }
1266}
1267
1268impl IntoAnyCalendar for IslamicUmmAlQura {
1269 fn to_any(self) -> AnyCalendar {
1270 AnyCalendar::IslamicUmmAlQura(self)
1271 }
1272 fn to_any_cloned(&self) -> AnyCalendar {
1273 AnyCalendar::IslamicUmmAlQura(self.clone())
1274 }
1275 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1276 AnyDateInner::IslamicUmmAlQura(*d)
1277 }
1278}
1279
1280impl IntoAnyCalendar for Iso {
1281 fn to_any(self) -> AnyCalendar {
1282 AnyCalendar::Iso(Iso)
1283 }
1284 fn to_any_cloned(&self) -> AnyCalendar {
1285 AnyCalendar::Iso(Iso)
1286 }
1287 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1288 AnyDateInner::Iso(*d)
1289 }
1290}
1291
1292impl IntoAnyCalendar for Japanese {
1293 fn to_any(self) -> AnyCalendar {
1294 AnyCalendar::Japanese(self)
1295 }
1296 fn to_any_cloned(&self) -> AnyCalendar {
1297 AnyCalendar::Japanese(self.clone())
1298 }
1299 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1300 AnyDateInner::Japanese(*d)
1301 }
1302}
1303
1304impl IntoAnyCalendar for JapaneseExtended {
1305 fn to_any(self) -> AnyCalendar {
1306 AnyCalendar::JapaneseExtended(self)
1307 }
1308 fn to_any_cloned(&self) -> AnyCalendar {
1309 AnyCalendar::JapaneseExtended(self.clone())
1310 }
1311 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1312 AnyDateInner::JapaneseExtended(*d)
1313 }
1314}
1315
1316impl IntoAnyCalendar for Persian {
1317 fn to_any(self) -> AnyCalendar {
1318 AnyCalendar::Persian(Persian)
1319 }
1320 fn to_any_cloned(&self) -> AnyCalendar {
1321 AnyCalendar::Persian(Persian)
1322 }
1323 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1324 AnyDateInner::Persian(*d)
1325 }
1326}
1327
1328impl IntoAnyCalendar for Roc {
1329 fn to_any(self) -> AnyCalendar {
1330 AnyCalendar::Roc(Roc)
1331 }
1332 fn to_any_cloned(&self) -> AnyCalendar {
1333 AnyCalendar::Roc(Roc)
1334 }
1335 fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
1336 AnyDateInner::Roc(*d)
1337 }
1338}
1339
1340#[cfg(test)]
1341mod tests {
1342 use super::*;
1343 use crate::Ref;
1344 use core::convert::TryInto;
1345
1346 fn single_test_roundtrip(
1347 calendar: Ref<AnyCalendar>,
1348 era: &str,
1349 year: i32,
1350 month_code: &str,
1351 day: u8,
1352 ) {
1353 let era = types::Era(era.parse().expect("era must parse"));
1354 let month = types::MonthCode(month_code.parse().expect("month code must parse"));
1355
1356 let date = Date::try_new_from_codes(era, year, month, day, calendar).unwrap_or_else(|e| {
1357 panic!(
1358 "Failed to construct date for {} with {:?}, {}, {}, {}: {}",
1359 calendar.debug_name(),
1360 era,
1361 year,
1362 month,
1363 day,
1364 e,
1365 )
1366 });
1367
1368 let roundtrip_year = date.year();
1369 let roundtrip_era = roundtrip_year.era;
1370 let roundtrip_year = roundtrip_year.number;
1371 let roundtrip_month = date.month().code;
1372 let roundtrip_day = date.day_of_month().0.try_into().expect("Must fit in u8");
1373
1374 assert_eq!(
1375 (era, year, month, day),
1376 (
1377 roundtrip_era,
1378 roundtrip_year,
1379 roundtrip_month,
1380 roundtrip_day
1381 ),
1382 "Failed to roundtrip for calendar {}",
1383 calendar.debug_name()
1384 );
1385
1386 let iso = date.to_iso();
1387 let reconstructed = Date::new_from_iso(iso, calendar);
1388 assert_eq!(
1389 date, reconstructed,
1390 "Failed to roundtrip via iso with {era:?}, {year}, {month}, {day}"
1391 )
1392 }
1393
1394 fn single_test_error(
1395 calendar: Ref<AnyCalendar>,
1396 era: &str,
1397 year: i32,
1398 month_code: &str,
1399 day: u8,
1400 error: CalendarError,
1401 ) {
1402 let era = types::Era(era.parse().expect("era must parse"));
1403 let month = types::MonthCode(month_code.parse().expect("month code must parse"));
1404
1405 let date = Date::try_new_from_codes(era, year, month, day, calendar);
1406 assert_eq!(
1407 date,
1408 Err(error),
1409 "Construction with {era:?}, {year}, {month}, {day} did not return {error:?}"
1410 )
1411 }
1412
1413 #[test]
1414 fn test_any_construction() {
1415 let buddhist = AnyCalendar::new(AnyCalendarKind::Buddhist);
1416 let chinese = AnyCalendar::new(AnyCalendarKind::Chinese);
1417 let coptic = AnyCalendar::new(AnyCalendarKind::Coptic);
1418 let dangi = AnyCalendar::new(AnyCalendarKind::Dangi);
1419 let ethioaa = AnyCalendar::new(AnyCalendarKind::EthiopianAmeteAlem);
1420 let ethiopian = AnyCalendar::new(AnyCalendarKind::Ethiopian);
1421 let gregorian = AnyCalendar::new(AnyCalendarKind::Gregorian);
1422 let hebrew = AnyCalendar::new(AnyCalendarKind::Hebrew);
1423 let indian = AnyCalendar::new(AnyCalendarKind::Indian);
1424 let islamic_civil: AnyCalendar = AnyCalendar::new(AnyCalendarKind::IslamicCivil);
1425 let islamic_observational: AnyCalendar =
1426 AnyCalendar::new(AnyCalendarKind::IslamicObservational);
1427 let islamic_tabular: AnyCalendar = AnyCalendar::new(AnyCalendarKind::IslamicTabular);
1428 let islamic_umm_al_qura: AnyCalendar = AnyCalendar::new(AnyCalendarKind::IslamicUmmAlQura);
1429 let japanese = AnyCalendar::new(AnyCalendarKind::Japanese);
1430 let japanext = AnyCalendar::new(AnyCalendarKind::JapaneseExtended);
1431 let persian = AnyCalendar::new(AnyCalendarKind::Persian);
1432 let roc = AnyCalendar::new(AnyCalendarKind::Roc);
1433 let buddhist = Ref(&buddhist);
1434 let chinese = Ref(&chinese);
1435 let coptic = Ref(&coptic);
1436 let dangi = Ref(&dangi);
1437 let ethioaa = Ref(ðioaa);
1438 let ethiopian = Ref(ðiopian);
1439 let gregorian = Ref(&gregorian);
1440 let hebrew = Ref(&hebrew);
1441 let indian = Ref(&indian);
1442 let islamic_civil = Ref(&islamic_civil);
1443 let islamic_observational = Ref(&islamic_observational);
1444 let islamic_tabular = Ref(&islamic_tabular);
1445 let islamic_umm_al_qura = Ref(&islamic_umm_al_qura);
1446 let japanese = Ref(&japanese);
1447 let japanext = Ref(&japanext);
1448 let persian = Ref(&persian);
1449 let roc = Ref(&roc);
1450
1451 single_test_roundtrip(buddhist, "be", 100, "M03", 1);
1452 single_test_roundtrip(buddhist, "be", 2000, "M03", 1);
1453 single_test_roundtrip(buddhist, "be", -100, "M03", 1);
1454 single_test_error(
1455 buddhist,
1456 "be",
1457 100,
1458 "M13",
1459 1,
1460 CalendarError::UnknownMonthCode(
1461 "M13".parse().unwrap(),
1462 AnyCalendarKind::Buddhist.debug_name(),
1463 ),
1464 );
1465
1466 single_test_roundtrip(coptic, "ad", 100, "M03", 1);
1467 single_test_roundtrip(coptic, "ad", 2000, "M03", 1);
1468 single_test_roundtrip(coptic, "ad", 100, "M13", 1);
1471 single_test_error(
1472 coptic,
1473 "ad",
1474 100,
1475 "M14",
1476 1,
1477 CalendarError::UnknownMonthCode(
1478 "M14".parse().unwrap(),
1479 AnyCalendarKind::Coptic.debug_name(),
1480 ),
1481 );
1482 single_test_error(coptic, "ad", 0, "M03", 1, CalendarError::OutOfRange);
1483 single_test_error(coptic, "bd", 0, "M03", 1, CalendarError::OutOfRange);
1484
1485 single_test_roundtrip(ethiopian, "incar", 100, "M03", 1);
1486 single_test_roundtrip(ethiopian, "incar", 2000, "M03", 1);
1487 single_test_roundtrip(ethiopian, "incar", 2000, "M13", 1);
1488 single_test_error(ethiopian, "incar", 0, "M03", 1, CalendarError::OutOfRange);
1491 single_test_error(
1492 ethiopian,
1493 "pre-incar",
1494 0,
1495 "M03",
1496 1,
1497 CalendarError::OutOfRange,
1498 );
1499 single_test_error(
1500 ethiopian,
1501 "incar",
1502 100,
1503 "M14",
1504 1,
1505 CalendarError::UnknownMonthCode(
1506 "M14".parse().unwrap(),
1507 AnyCalendarKind::Ethiopian.debug_name(),
1508 ),
1509 );
1510
1511 single_test_roundtrip(ethioaa, "mundi", 7000, "M13", 1);
1512 single_test_roundtrip(ethioaa, "mundi", 7000, "M13", 1);
1513 single_test_error(
1516 ethiopian,
1517 "mundi",
1518 100,
1519 "M14",
1520 1,
1521 CalendarError::UnknownMonthCode(
1522 "M14".parse().unwrap(),
1523 AnyCalendarKind::Ethiopian.debug_name(),
1524 ),
1525 );
1526
1527 single_test_roundtrip(gregorian, "ce", 100, "M03", 1);
1528 single_test_roundtrip(gregorian, "ce", 2000, "M03", 1);
1529 single_test_roundtrip(gregorian, "bce", 100, "M03", 1);
1530 single_test_error(gregorian, "ce", 0, "M03", 1, CalendarError::OutOfRange);
1531 single_test_error(gregorian, "bce", 0, "M03", 1, CalendarError::OutOfRange);
1532
1533 single_test_error(
1534 gregorian,
1535 "bce",
1536 100,
1537 "M13",
1538 1,
1539 CalendarError::UnknownMonthCode(
1540 "M13".parse().unwrap(),
1541 AnyCalendarKind::Gregorian.debug_name(),
1542 ),
1543 );
1544
1545 single_test_roundtrip(indian, "saka", 100, "M03", 1);
1546 single_test_roundtrip(indian, "saka", 2000, "M12", 1);
1547 single_test_roundtrip(indian, "saka", -100, "M03", 1);
1548 single_test_roundtrip(indian, "saka", 0, "M03", 1);
1549 single_test_error(
1550 indian,
1551 "saka",
1552 100,
1553 "M13",
1554 1,
1555 CalendarError::UnknownMonthCode(
1556 "M13".parse().unwrap(),
1557 AnyCalendarKind::Indian.debug_name(),
1558 ),
1559 );
1560
1561 single_test_roundtrip(chinese, "chinese", 400, "M02", 5);
1562 single_test_roundtrip(chinese, "chinese", 4660, "M07", 29);
1563 single_test_roundtrip(chinese, "chinese", -100, "M11", 12);
1564 single_test_error(
1565 chinese,
1566 "chinese",
1567 4658,
1568 "M13",
1569 1,
1570 CalendarError::UnknownMonthCode(
1571 "M13".parse().unwrap(),
1572 AnyCalendarKind::Chinese.debug_name(),
1573 ),
1574 );
1575
1576 single_test_roundtrip(dangi, "dangi", 400, "M02", 5);
1577 single_test_roundtrip(dangi, "dangi", 4660, "M08", 29);
1578 single_test_roundtrip(dangi, "dangi", -1300, "M11", 12);
1579 single_test_error(
1580 dangi,
1581 "dangi",
1582 10393,
1583 "M00L",
1584 1,
1585 CalendarError::UnknownMonthCode(
1586 "M00L".parse().unwrap(),
1587 AnyCalendarKind::Dangi.debug_name(),
1588 ),
1589 );
1590
1591 single_test_roundtrip(japanese, "reiwa", 3, "M03", 1);
1592 single_test_roundtrip(japanese, "heisei", 6, "M12", 1);
1593 single_test_roundtrip(japanese, "meiji", 10, "M03", 1);
1594 single_test_roundtrip(japanese, "ce", 1000, "M03", 1);
1595 single_test_roundtrip(japanese, "bce", 10, "M03", 1);
1596 single_test_error(japanese, "ce", 0, "M03", 1, CalendarError::OutOfRange);
1597 single_test_error(japanese, "bce", 0, "M03", 1, CalendarError::OutOfRange);
1598
1599 single_test_error(
1600 japanese,
1601 "reiwa",
1602 2,
1603 "M13",
1604 1,
1605 CalendarError::UnknownMonthCode(
1606 "M13".parse().unwrap(),
1607 AnyCalendarKind::Japanese.debug_name(),
1608 ),
1609 );
1610
1611 single_test_roundtrip(japanext, "reiwa", 3, "M03", 1);
1612 single_test_roundtrip(japanext, "heisei", 6, "M12", 1);
1613 single_test_roundtrip(japanext, "meiji", 10, "M03", 1);
1614 single_test_roundtrip(japanext, "tenpyokampo-749", 1, "M04", 20);
1615 single_test_roundtrip(japanext, "ce", 100, "M03", 1);
1616 single_test_roundtrip(japanext, "bce", 10, "M03", 1);
1617 single_test_error(japanext, "ce", 0, "M03", 1, CalendarError::OutOfRange);
1618 single_test_error(japanext, "bce", 0, "M03", 1, CalendarError::OutOfRange);
1619
1620 single_test_error(
1621 japanext,
1622 "reiwa",
1623 2,
1624 "M13",
1625 1,
1626 CalendarError::UnknownMonthCode(
1627 "M13".parse().unwrap(),
1628 AnyCalendarKind::JapaneseExtended.debug_name(),
1629 ),
1630 );
1631
1632 single_test_roundtrip(persian, "ah", 477, "M03", 1);
1633 single_test_roundtrip(persian, "ah", 2083, "M07", 21);
1634 single_test_roundtrip(persian, "ah", 1600, "M12", 20);
1635 single_test_error(
1636 persian,
1637 "ah",
1638 100,
1639 "M9",
1640 1,
1641 CalendarError::UnknownMonthCode(
1642 "M9".parse().unwrap(),
1643 AnyCalendarKind::Persian.debug_name(),
1644 ),
1645 );
1646
1647 single_test_roundtrip(hebrew, "hebrew", 5773, "M03", 1);
1648 single_test_roundtrip(hebrew, "hebrew", 4993, "M07", 21);
1649 single_test_roundtrip(hebrew, "hebrew", 5012, "M12", 20);
1650 single_test_error(
1651 hebrew,
1652 "hebrew",
1653 100,
1654 "M9",
1655 1,
1656 CalendarError::UnknownMonthCode(
1657 "M9".parse().unwrap(),
1658 AnyCalendarKind::Hebrew.debug_name(),
1659 ),
1660 );
1661
1662 single_test_roundtrip(roc, "roc", 10, "M05", 3);
1663 single_test_roundtrip(roc, "roc-inverse", 15, "M01", 10);
1664 single_test_roundtrip(roc, "roc", 100, "M10", 30);
1665
1666 single_test_roundtrip(islamic_observational, "islamic", 477, "M03", 1);
1667 single_test_roundtrip(islamic_observational, "islamic", 2083, "M07", 21);
1668 single_test_roundtrip(islamic_observational, "islamic", 1600, "M12", 20);
1669 single_test_error(
1670 islamic_observational,
1671 "islamic",
1672 100,
1673 "M9",
1674 1,
1675 CalendarError::UnknownMonthCode(
1676 "M9".parse().unwrap(),
1677 AnyCalendarKind::IslamicObservational.debug_name(),
1678 ),
1679 );
1680
1681 single_test_roundtrip(islamic_civil, "islamic", 477, "M03", 1);
1682 single_test_roundtrip(islamic_civil, "islamic", 2083, "M07", 21);
1683 single_test_roundtrip(islamic_civil, "islamic", 1600, "M12", 20);
1684 single_test_error(
1685 islamic_civil,
1686 "islamic",
1687 100,
1688 "M9",
1689 1,
1690 CalendarError::UnknownMonthCode(
1691 "M9".parse().unwrap(),
1692 AnyCalendarKind::IslamicCivil.debug_name(),
1693 ),
1694 );
1695
1696 single_test_roundtrip(islamic_umm_al_qura, "islamic", 477, "M03", 1);
1697 single_test_roundtrip(islamic_umm_al_qura, "islamic", 2083, "M07", 21);
1698 single_test_roundtrip(islamic_umm_al_qura, "islamic", 1600, "M12", 20);
1699 single_test_error(
1700 islamic_umm_al_qura,
1701 "islamic",
1702 100,
1703 "M9",
1704 1,
1705 CalendarError::UnknownMonthCode(
1706 "M9".parse().unwrap(),
1707 AnyCalendarKind::IslamicUmmAlQura.debug_name(),
1708 ),
1709 );
1710
1711 single_test_roundtrip(islamic_tabular, "islamic", 477, "M03", 1);
1712 single_test_roundtrip(islamic_tabular, "islamic", 2083, "M07", 21);
1713 single_test_roundtrip(islamic_tabular, "islamic", 1600, "M12", 20);
1714 single_test_error(
1715 islamic_tabular,
1716 "islamic",
1717 100,
1718 "M9",
1719 1,
1720 CalendarError::UnknownMonthCode(
1721 "M9".parse().unwrap(),
1722 AnyCalendarKind::IslamicTabular.debug_name(),
1723 ),
1724 );
1725 }
1726}