1use crate::provider::{neo::*, *};
8use crate::scaffold::UnstableSealed;
9use crate::{DateTimeFormatterPreferences, MismatchedCalendarError};
10use core::marker::PhantomData;
11use icu_calendar::cal::{self, *};
12use icu_calendar::{AnyCalendar, AnyCalendarKind, AsCalendar, Date, IntoAnyCalendar, Ref};
13use icu_provider::marker::NeverMarker;
14use icu_provider::prelude::*;
15use icu_time::{
16 zone::{models::TimeZoneModel, UtcOffset},
17 DateTime, Time, TimeZoneInfo, ZonedDateTime,
18};
19
20pub trait CldrCalendar: UnstableSealed {
30 type YearNamesV1: DataMarker<DataStruct = YearNames<'static>>;
32
33 type MonthNamesV1: DataMarker<DataStruct = MonthNames<'static>>;
35
36 type SkeletaV1: DataMarker<DataStruct = PackedPatterns<'static>>;
38}
39
40impl CldrCalendar for () {
41 type YearNamesV1 = NeverMarker<YearNames<'static>>;
42 type MonthNamesV1 = NeverMarker<MonthNames<'static>>;
43 type SkeletaV1 = NeverMarker<PackedPatterns<'static>>;
44}
45
46impl CldrCalendar for Buddhist {
47 type YearNamesV1 = DatetimeNamesYearBuddhistV1;
48 type MonthNamesV1 = DatetimeNamesMonthBuddhistV1;
49 type SkeletaV1 = DatetimePatternsDateBuddhistV1;
50}
51
52impl CldrCalendar for ChineseTraditional {
53 type YearNamesV1 = DatetimeNamesYearChineseV1;
54 type MonthNamesV1 = DatetimeNamesMonthChineseV1;
55 type SkeletaV1 = DatetimePatternsDateChineseV1;
56}
57
58impl CldrCalendar for Coptic {
59 type YearNamesV1 = DatetimeNamesYearCopticV1;
60 type MonthNamesV1 = DatetimeNamesMonthCopticV1;
61 type SkeletaV1 = DatetimePatternsDateCopticV1;
62}
63
64impl CldrCalendar for KoreanTraditional {
65 type YearNamesV1 = DatetimeNamesYearDangiV1;
66 type MonthNamesV1 = DatetimeNamesMonthDangiV1;
67 type SkeletaV1 = DatetimePatternsDateDangiV1;
68}
69
70impl CldrCalendar for Ethiopian {
71 type YearNamesV1 = DatetimeNamesYearEthiopianV1;
72 type MonthNamesV1 = DatetimeNamesMonthEthiopianV1;
73 type SkeletaV1 = DatetimePatternsDateEthiopianV1;
74}
75
76impl CldrCalendar for Gregorian {
77 type YearNamesV1 = DatetimeNamesYearGregorianV1;
78 type MonthNamesV1 = DatetimeNamesMonthGregorianV1;
79 type SkeletaV1 = DatetimePatternsDateGregorianV1;
80}
81
82impl CldrCalendar for Hebrew {
83 type YearNamesV1 = DatetimeNamesYearHebrewV1;
84 type MonthNamesV1 = DatetimeNamesMonthHebrewV1;
85 type SkeletaV1 = DatetimePatternsDateHebrewV1;
86}
87
88impl CldrCalendar for Indian {
89 type YearNamesV1 = DatetimeNamesYearIndianV1;
90 type MonthNamesV1 = DatetimeNamesMonthIndianV1;
91 type SkeletaV1 = DatetimePatternsDateIndianV1;
92}
93
94pub trait FormattableHijriRules: hijri::unstable_internal::Rules + UnstableSealed {
127 type YearNamesV1: DataMarker<DataStruct = YearNames<'static>>;
129
130 type MonthNamesV1: DataMarker<DataStruct = MonthNames<'static>>;
132
133 type SkeletaV1: DataMarker<DataStruct = PackedPatterns<'static>>;
135}
136
137impl UnstableSealed for hijri::TabularAlgorithm {}
138impl FormattableHijriRules for hijri::TabularAlgorithm {
139 type YearNamesV1 = DatetimeNamesYearHijriV1;
140 type MonthNamesV1 = DatetimeNamesMonthHijriV1;
141 type SkeletaV1 = DatetimePatternsDateHijriV1;
142}
143
144impl UnstableSealed for hijri::UmmAlQura {}
145impl FormattableHijriRules for hijri::UmmAlQura {
146 type YearNamesV1 = DatetimeNamesYearHijriV1;
147 type MonthNamesV1 = DatetimeNamesMonthHijriV1;
148 type SkeletaV1 = DatetimePatternsDateHijriV1;
149}
150
151impl UnstableSealed for hijri::AstronomicalSimulation {}
152impl FormattableHijriRules for hijri::AstronomicalSimulation {
153 type YearNamesV1 = DatetimeNamesYearHijriV1;
154 type MonthNamesV1 = DatetimeNamesMonthHijriV1;
155 type SkeletaV1 = DatetimePatternsDateHijriV1;
156}
157
158impl<R: FormattableHijriRules> CldrCalendar for Hijri<R> {
159 type YearNamesV1 = R::YearNamesV1;
160 type MonthNamesV1 = R::MonthNamesV1;
161 type SkeletaV1 = R::SkeletaV1;
162}
163
164impl CldrCalendar for Japanese {
165 type YearNamesV1 = DatetimeNamesYearJapaneseV1;
166 type MonthNamesV1 = DatetimeNamesMonthJapaneseV1;
167 type SkeletaV1 = DatetimePatternsDateJapaneseV1;
168}
169
170impl CldrCalendar for JapaneseExtended {
171 type YearNamesV1 = DatetimeNamesYearJapanextV1;
172 type MonthNamesV1 = DatetimeNamesMonthJapanextV1;
173 type SkeletaV1 = DatetimePatternsDateJapanextV1;
174}
175
176impl CldrCalendar for Persian {
177 type YearNamesV1 = DatetimeNamesYearPersianV1;
178 type MonthNamesV1 = DatetimeNamesMonthPersianV1;
179 type SkeletaV1 = DatetimePatternsDatePersianV1;
180}
181
182impl CldrCalendar for Roc {
183 type YearNamesV1 = DatetimeNamesYearRocV1;
184 type MonthNamesV1 = DatetimeNamesMonthRocV1;
185 type SkeletaV1 = DatetimePatternsDateRocV1;
186}
187
188impl UnstableSealed for () {}
189impl UnstableSealed for Buddhist {}
190impl UnstableSealed for ChineseTraditional {}
191impl UnstableSealed for Coptic {}
192impl UnstableSealed for KoreanTraditional {}
193impl UnstableSealed for Ethiopian {}
194impl UnstableSealed for Gregorian {}
195impl UnstableSealed for Hebrew {}
196impl UnstableSealed for Indian {}
197impl<R: hijri::unstable_internal::Rules> UnstableSealed for Hijri<R> {}
198impl UnstableSealed for Japanese {}
199impl UnstableSealed for JapaneseExtended {}
200impl UnstableSealed for Persian {}
201impl UnstableSealed for Roc {}
202
203pub trait CalMarkers<M>: UnstableSealed
215where
216 M: DynamicDataMarker,
217{
218 type Buddhist: DataMarker<DataStruct = M::DataStruct>;
220 type Chinese: DataMarker<DataStruct = M::DataStruct>;
222 type Coptic: DataMarker<DataStruct = M::DataStruct>;
224 type Dangi: DataMarker<DataStruct = M::DataStruct>;
226 type Ethiopian: DataMarker<DataStruct = M::DataStruct>;
228 type Gregorian: DataMarker<DataStruct = M::DataStruct>;
230 type Hebrew: DataMarker<DataStruct = M::DataStruct>;
232 type Indian: DataMarker<DataStruct = M::DataStruct>;
234 type Hijri: DataMarker<DataStruct = M::DataStruct>;
236 type Japanese: DataMarker<DataStruct = M::DataStruct>;
238 type Persian: DataMarker<DataStruct = M::DataStruct>;
240 type Roc: DataMarker<DataStruct = M::DataStruct>;
242}
243
244#[derive(Debug)]
246#[allow(clippy::exhaustive_enums)] pub enum FullDataCalMarkers {}
248
249impl UnstableSealed for FullDataCalMarkers {}
250
251#[derive(Debug)]
253#[allow(clippy::exhaustive_enums)] pub enum NoDataCalMarkers {}
255
256impl UnstableSealed for NoDataCalMarkers {}
257
258impl<M> CalMarkers<M> for NoDataCalMarkers
259where
260 M: DynamicDataMarker,
261{
262 type Buddhist = NeverMarker<M::DataStruct>;
263 type Chinese = NeverMarker<M::DataStruct>;
264 type Coptic = NeverMarker<M::DataStruct>;
265 type Dangi = NeverMarker<M::DataStruct>;
266 type Ethiopian = NeverMarker<M::DataStruct>;
267 type Gregorian = NeverMarker<M::DataStruct>;
268 type Hebrew = NeverMarker<M::DataStruct>;
269 type Indian = NeverMarker<M::DataStruct>;
270 type Hijri = NeverMarker<M::DataStruct>;
271 type Japanese = NeverMarker<M::DataStruct>;
272 type Persian = NeverMarker<M::DataStruct>;
273 type Roc = NeverMarker<M::DataStruct>;
274}
275
276pub trait IntoFormattableAnyCalendar: CldrCalendar + IntoAnyCalendar {}
280
281impl IntoFormattableAnyCalendar for Buddhist {}
283impl IntoFormattableAnyCalendar for ChineseTraditional {}
284impl IntoFormattableAnyCalendar for Coptic {}
285impl IntoFormattableAnyCalendar for KoreanTraditional {}
286impl IntoFormattableAnyCalendar for Ethiopian {}
287impl IntoFormattableAnyCalendar for Gregorian {}
288impl IntoFormattableAnyCalendar for Hebrew {}
289impl IntoFormattableAnyCalendar for Indian {}
290impl IntoFormattableAnyCalendar for Hijri<hijri::TabularAlgorithm> {}
291impl IntoFormattableAnyCalendar for Hijri<hijri::AstronomicalSimulation> {}
292impl IntoFormattableAnyCalendar for Hijri<hijri::UmmAlQura> {}
293impl IntoFormattableAnyCalendar for Japanese {}
295impl IntoFormattableAnyCalendar for Persian {}
297impl IntoFormattableAnyCalendar for Roc {}
298
299#[derive(Debug, Clone, Copy, PartialEq)]
301pub(crate) enum FormattableAnyCalendarKind {
302 Buddhist,
303 Chinese,
304 Coptic,
305 Dangi,
306 Ethiopian,
307 EthiopianAmeteAlem,
308 Gregorian,
309 Hebrew,
310 Indian,
311 HijriTabularTypeIIFriday,
312 HijriTabularTypeIIThursday,
314 HijriUmmAlQura,
315 Japanese,
316 Persian,
318 Roc,
319}
320
321impl FormattableAnyCalendarKind {
322 pub(crate) fn try_from_any_calendar_kind(kind: AnyCalendarKind) -> Option<Self> {
323 use AnyCalendarKind::*;
324 let res = match kind {
325 Buddhist => Self::Buddhist,
326 Chinese => Self::Chinese,
327 Coptic => Self::Coptic,
328 Dangi => Self::Dangi,
329 Ethiopian => Self::Ethiopian,
330 EthiopianAmeteAlem => Self::EthiopianAmeteAlem,
331 Gregorian => Self::Gregorian,
332 Hebrew => Self::Hebrew,
333 Indian => Self::Indian,
334 HijriTabularTypeIIFriday => Self::HijriTabularTypeIIFriday,
335 HijriSimulatedMecca => return None,
336 HijriTabularTypeIIThursday => Self::HijriTabularTypeIIThursday,
337 HijriUmmAlQura => Self::HijriUmmAlQura,
338 Iso => return None,
339 Japanese => Self::Japanese,
340 JapaneseExtended => return None,
341 Persian => Self::Persian,
342 Roc => Self::Roc,
343 _ => {
344 debug_assert!(false, "cross-crate exhaustive match");
345 return None;
346 }
347 };
348 Some(res)
349 }
350
351 pub(crate) fn from_preferences(mut prefs: DateTimeFormatterPreferences) -> Self {
352 if let Some(res) = Self::try_from_any_calendar_kind(AnyCalendarKind::new((&prefs).into())) {
353 return res;
354 }
355
356 prefs.calendar_algorithm = None;
360 if let Some(res) = Self::try_from_any_calendar_kind(AnyCalendarKind::new((&prefs).into())) {
361 return res;
362 }
363
364 debug_assert!(false, "all locale-default calendars are supported");
365 FormattableAnyCalendarKind::Coptic
367 }
368}
369
370#[test]
371fn test_calendar_fallback() {
372 use icu_locale_core::locale;
373 assert_eq!(
374 FormattableAnyCalendarKind::from_preferences(locale!("en-TH-u-ca-iso8601").into()),
375 FormattableAnyCalendarKind::Buddhist
376 );
377 assert_eq!(
378 FormattableAnyCalendarKind::from_preferences(locale!("en-TH").into()),
379 FormattableAnyCalendarKind::Buddhist
380 );
381 assert_eq!(
382 FormattableAnyCalendarKind::from_preferences(locale!("en-SA-u-ca-islamic").into()),
383 FormattableAnyCalendarKind::HijriUmmAlQura
384 );
385 assert_eq!(
386 FormattableAnyCalendarKind::from_preferences(locale!("en-IL-u-ca-islamic").into()),
387 FormattableAnyCalendarKind::HijriTabularTypeIIFriday
388 );
389}
390
391#[derive(Debug, Clone)]
393pub(crate) struct FormattableAnyCalendar {
394 any_calendar: AnyCalendar,
395 kind: FormattableAnyCalendarKind,
396}
397
398impl FormattableAnyCalendar {
399 pub(crate) fn from_calendar(calendar: impl IntoFormattableAnyCalendar) -> Self {
400 let any_calendar = calendar.to_any();
401 let kind = any_calendar.kind();
402 let kind = FormattableAnyCalendarKind::try_from_any_calendar_kind(any_calendar.kind())
403 .unwrap_or_else(|| {
404 debug_assert!(false, "{kind:?} is not a FormattableAnyCalendarKind");
405 FormattableAnyCalendarKind::Coptic
406 });
407 Self { any_calendar, kind }
408 }
409
410 pub(crate) fn try_from_any_calendar(any_calendar: AnyCalendar) -> Option<Self> {
411 let kind = FormattableAnyCalendarKind::try_from_any_calendar_kind(any_calendar.kind())?;
412 Some(Self { any_calendar, kind })
413 }
414
415 pub(crate) fn kind(&self) -> FormattableAnyCalendarKind {
416 self.kind
417 }
418
419 #[cfg(feature = "compiled_data")]
420 pub(crate) fn try_new(kind: FormattableAnyCalendarKind) -> Result<Self, DataError> {
421 use FormattableAnyCalendarKind::*;
422 let any_calendar = match kind {
423 Buddhist => AnyCalendar::Buddhist(cal::Buddhist),
424 Chinese => AnyCalendar::Chinese(cal::ChineseTraditional::new()),
425 Coptic => AnyCalendar::Coptic(cal::Coptic),
426 Dangi => AnyCalendar::Dangi(cal::KoreanTraditional::new()),
427 Ethiopian => AnyCalendar::Ethiopian(cal::Ethiopian::new()),
428 EthiopianAmeteAlem => AnyCalendar::Ethiopian(cal::Ethiopian::new_with_era_style(
429 cal::EthiopianEraStyle::AmeteAlem,
430 )),
431 Gregorian => AnyCalendar::Gregorian(cal::Gregorian),
432 Hebrew => AnyCalendar::Hebrew(cal::Hebrew),
433 Indian => AnyCalendar::Indian(cal::Indian),
434 HijriTabularTypeIIFriday => AnyCalendar::HijriTabular(cal::Hijri::new_tabular(
435 hijri::TabularAlgorithmLeapYears::TypeII,
436 hijri::TabularAlgorithmEpoch::Friday,
437 )),
438 HijriTabularTypeIIThursday => AnyCalendar::HijriTabular(cal::Hijri::new_tabular(
439 hijri::TabularAlgorithmLeapYears::TypeII,
440 hijri::TabularAlgorithmEpoch::Thursday,
441 )),
442 HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(cal::Hijri::new_umm_al_qura()),
443 Japanese => AnyCalendar::Japanese(cal::Japanese::new()),
444 Persian => AnyCalendar::Persian(cal::Persian),
445 Roc => AnyCalendar::Roc(cal::Roc),
446 };
447 Ok(Self { any_calendar, kind })
448 }
449
450 #[cfg(feature = "serde")]
451 pub(crate) fn try_new_with_buffer_provider<P>(
452 provider: &P,
453 kind: FormattableAnyCalendarKind,
454 ) -> Result<Self, DataError>
455 where
456 P: ?Sized + BufferProvider,
457 {
458 use FormattableAnyCalendarKind::*;
459 let any_calendar = match kind {
460 Buddhist => AnyCalendar::Buddhist(cal::Buddhist),
461 Chinese => AnyCalendar::Chinese(cal::ChineseTraditional::new()),
462 Coptic => AnyCalendar::Coptic(cal::Coptic),
463 Dangi => AnyCalendar::Dangi(cal::KoreanTraditional::new()),
464 Ethiopian => AnyCalendar::Ethiopian(cal::Ethiopian::new()),
465 EthiopianAmeteAlem => AnyCalendar::Ethiopian(cal::Ethiopian::new_with_era_style(
466 cal::EthiopianEraStyle::AmeteAlem,
467 )),
468 Gregorian => AnyCalendar::Gregorian(cal::Gregorian),
469 Hebrew => AnyCalendar::Hebrew(cal::Hebrew),
470 Indian => AnyCalendar::Indian(cal::Indian),
471 HijriTabularTypeIIFriday => AnyCalendar::HijriTabular(cal::Hijri::new_tabular(
472 hijri::TabularAlgorithmLeapYears::TypeII,
473 hijri::TabularAlgorithmEpoch::Friday,
474 )),
475 HijriTabularTypeIIThursday => AnyCalendar::HijriTabular(cal::Hijri::new_tabular(
476 hijri::TabularAlgorithmLeapYears::TypeII,
477 hijri::TabularAlgorithmEpoch::Thursday,
478 )),
479 HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(cal::Hijri::new_umm_al_qura()),
480 Japanese => {
481 AnyCalendar::Japanese(cal::Japanese::try_new_with_buffer_provider(provider)?)
482 }
483 Persian => AnyCalendar::Persian(cal::Persian),
484 Roc => AnyCalendar::Roc(cal::Roc),
485 };
486 Ok(Self { any_calendar, kind })
487 }
488
489 pub(crate) fn try_new_unstable<P>(
490 provider: &P,
491 kind: FormattableAnyCalendarKind,
492 ) -> Result<Self, DataError>
493 where
494 P: ?Sized + DataProvider<icu_calendar::provider::CalendarJapaneseModernV1>,
495 {
496 use FormattableAnyCalendarKind::*;
497 let any_calendar = match kind {
498 Buddhist => AnyCalendar::Buddhist(cal::Buddhist),
499 Chinese => AnyCalendar::Chinese(cal::ChineseTraditional::new()),
500 Coptic => AnyCalendar::Coptic(cal::Coptic),
501 Dangi => AnyCalendar::Dangi(cal::KoreanTraditional::new()),
502 Ethiopian => AnyCalendar::Ethiopian(cal::Ethiopian::new()),
503 EthiopianAmeteAlem => AnyCalendar::Ethiopian(cal::Ethiopian::new_with_era_style(
504 cal::EthiopianEraStyle::AmeteAlem,
505 )),
506 Gregorian => AnyCalendar::Gregorian(cal::Gregorian),
507 Hebrew => AnyCalendar::Hebrew(cal::Hebrew),
508 Indian => AnyCalendar::Indian(cal::Indian),
509 HijriTabularTypeIIFriday => AnyCalendar::HijriTabular(cal::Hijri::new_tabular(
510 hijri::TabularAlgorithmLeapYears::TypeII,
511 hijri::TabularAlgorithmEpoch::Friday,
512 )),
513 HijriTabularTypeIIThursday => AnyCalendar::HijriTabular(cal::Hijri::new_tabular(
514 hijri::TabularAlgorithmLeapYears::TypeII,
515 hijri::TabularAlgorithmEpoch::Thursday,
516 )),
517 HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(cal::Hijri::new_umm_al_qura()),
518 Japanese => AnyCalendar::Japanese(cal::Japanese::try_new_unstable(provider)?),
519 Persian => AnyCalendar::Persian(cal::Persian),
520 Roc => AnyCalendar::Roc(cal::Roc),
521 };
522 Ok(Self { any_calendar, kind })
523 }
524
525 pub(crate) fn into_untagged(self) -> UntaggedFormattableAnyCalendar {
526 UntaggedFormattableAnyCalendar {
527 any_calendar: self.any_calendar,
528 }
529 }
530}
531
532#[derive(Debug, Clone)]
533pub(crate) struct UntaggedFormattableAnyCalendar {
534 any_calendar: AnyCalendar,
536}
537
538impl UntaggedFormattableAnyCalendar {
540 pub(crate) fn into_tagged(self) -> FormattableAnyCalendar {
541 let kind = FormattableAnyCalendarKind::try_from_any_calendar_kind(self.any_calendar.kind())
542 .unwrap_or_else(|| {
543 debug_assert!(false, "unreachable by invariant");
544 FormattableAnyCalendarKind::Coptic
546 });
547 FormattableAnyCalendar {
548 any_calendar: self.any_calendar,
549 kind,
550 }
551 }
552
553 pub(crate) fn any_calendar(&self) -> &AnyCalendar {
554 &self.any_calendar
555 }
556
557 pub(crate) fn take_any_calendar(self) -> AnyCalendar {
558 self.any_calendar
559 }
560}
561
562pub(crate) struct FormattableAnyCalendarNamesLoader<H, P> {
563 provider: P,
564 kind: FormattableAnyCalendarKind,
565 _helper: PhantomData<H>,
566}
567
568impl<H, P> FormattableAnyCalendarNamesLoader<H, P> {
569 pub(crate) fn new(provider: P, kind: FormattableAnyCalendarKind) -> Self {
570 Self {
571 provider,
572 kind,
573 _helper: PhantomData,
574 }
575 }
576}
577
578impl<M, H, P> BoundDataProvider<M> for FormattableAnyCalendarNamesLoader<H, P>
579where
580 M: DynamicDataMarker,
581 H: CalMarkers<M>,
582 P: Sized
583 + DataProvider<H::Buddhist>
584 + DataProvider<H::Chinese>
585 + DataProvider<H::Coptic>
586 + DataProvider<H::Dangi>
587 + DataProvider<H::Ethiopian>
588 + DataProvider<H::Gregorian>
589 + DataProvider<H::Hebrew>
590 + DataProvider<H::Indian>
591 + DataProvider<H::Hijri>
592 + DataProvider<H::Japanese>
593 + DataProvider<H::Persian>
594 + DataProvider<H::Roc>,
595{
596 fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
597 use FormattableAnyCalendarKind::*;
598 let p = &self.provider;
599 match self.kind {
600 Buddhist => H::Buddhist::bind(p).load_bound(req),
601 Chinese => H::Chinese::bind(p).load_bound(req),
602 Coptic => H::Coptic::bind(p).load_bound(req),
603 Dangi => H::Dangi::bind(p).load_bound(req),
604 Ethiopian | EthiopianAmeteAlem => H::Ethiopian::bind(p).load_bound(req),
605 Gregorian => H::Gregorian::bind(p).load_bound(req),
606 Hebrew => H::Hebrew::bind(p).load_bound(req),
607 Indian => H::Indian::bind(p).load_bound(req),
608 HijriTabularTypeIIFriday | HijriTabularTypeIIThursday | HijriUmmAlQura => {
609 H::Hijri::bind(p).load_bound(req)
610 }
611 Japanese => H::Japanese::bind(p).load_bound(req),
612 Persian => H::Persian::bind(p).load_bound(req),
613 Roc => H::Roc::bind(p).load_bound(req),
614 }
615 }
616 fn bound_marker(&self) -> DataMarkerInfo {
617 use FormattableAnyCalendarKind::*;
618 match self.kind {
619 Buddhist => H::Buddhist::INFO,
620 Chinese => H::Chinese::INFO,
621 Coptic => H::Coptic::INFO,
622 Dangi => H::Dangi::INFO,
623 Ethiopian | EthiopianAmeteAlem => H::Ethiopian::INFO,
624 Gregorian => H::Gregorian::INFO,
625 Hebrew => H::Hebrew::INFO,
626 Indian => H::Indian::INFO,
627 HijriTabularTypeIIFriday | HijriTabularTypeIIThursday | HijriUmmAlQura => {
628 H::Hijri::INFO
629 }
630 Japanese => H::Japanese::INFO,
631 Persian => H::Persian::INFO,
632 Roc => H::Roc::INFO,
633 }
634 }
635}
636
637impl CalMarkers<YearNamesV1> for FullDataCalMarkers {
638 type Buddhist = <Buddhist as CldrCalendar>::YearNamesV1;
639 type Chinese = <ChineseTraditional as CldrCalendar>::YearNamesV1;
640 type Coptic = <Coptic as CldrCalendar>::YearNamesV1;
641 type Dangi = <KoreanTraditional as CldrCalendar>::YearNamesV1;
642 type Ethiopian = <Ethiopian as CldrCalendar>::YearNamesV1;
643 type Gregorian = <Gregorian as CldrCalendar>::YearNamesV1;
644 type Hebrew = <Hebrew as CldrCalendar>::YearNamesV1;
645 type Indian = <Indian as CldrCalendar>::YearNamesV1;
646 type Hijri = <Hijri<hijri::UmmAlQura> as CldrCalendar>::YearNamesV1;
647 type Japanese = <Japanese as CldrCalendar>::YearNamesV1;
648 type Persian = <Persian as CldrCalendar>::YearNamesV1;
649 type Roc = <Roc as CldrCalendar>::YearNamesV1;
650}
651
652impl CalMarkers<MonthNamesV1> for FullDataCalMarkers {
653 type Buddhist = <Buddhist as CldrCalendar>::MonthNamesV1;
654 type Chinese = <ChineseTraditional as CldrCalendar>::MonthNamesV1;
655 type Coptic = <Coptic as CldrCalendar>::MonthNamesV1;
656 type Dangi = <KoreanTraditional as CldrCalendar>::MonthNamesV1;
657 type Ethiopian = <Ethiopian as CldrCalendar>::MonthNamesV1;
658 type Gregorian = <Gregorian as CldrCalendar>::MonthNamesV1;
659 type Hebrew = <Hebrew as CldrCalendar>::MonthNamesV1;
660 type Indian = <Indian as CldrCalendar>::MonthNamesV1;
661 type Hijri = <Hijri<hijri::UmmAlQura> as CldrCalendar>::MonthNamesV1;
662 type Japanese = <Japanese as CldrCalendar>::MonthNamesV1;
663 type Persian = <Persian as CldrCalendar>::MonthNamesV1;
664 type Roc = <Roc as CldrCalendar>::MonthNamesV1;
665}
666
667impl CalMarkers<ErasedPackedPatterns> for FullDataCalMarkers {
668 type Buddhist = <Buddhist as CldrCalendar>::SkeletaV1;
669 type Chinese = <ChineseTraditional as CldrCalendar>::SkeletaV1;
670 type Coptic = <Coptic as CldrCalendar>::SkeletaV1;
671 type Dangi = <KoreanTraditional as CldrCalendar>::SkeletaV1;
672 type Ethiopian = <Ethiopian as CldrCalendar>::SkeletaV1;
673 type Gregorian = <Gregorian as CldrCalendar>::SkeletaV1;
674 type Hebrew = <Hebrew as CldrCalendar>::SkeletaV1;
675 type Indian = <Indian as CldrCalendar>::SkeletaV1;
676 type Hijri = <Hijri<hijri::UmmAlQura> as CldrCalendar>::SkeletaV1;
677 type Japanese = <Japanese as CldrCalendar>::SkeletaV1;
678 type Persian = <Persian as CldrCalendar>::SkeletaV1;
679 type Roc = <Roc as CldrCalendar>::SkeletaV1;
680}
681
682pub trait ConvertCalendar {
685 type Converted<'a>: Sized;
687 fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a>;
689}
690
691impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> ConvertCalendar for Date<A> {
692 type Converted<'a> = Date<Ref<'a, AnyCalendar>>;
693 #[inline]
694 fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
695 self.to_calendar(Ref(calendar))
696 }
697}
698
699impl ConvertCalendar for Time {
700 type Converted<'a> = Time;
701 #[inline]
702 fn to_calendar<'a>(&self, _: &'a AnyCalendar) -> Self::Converted<'a> {
703 *self
704 }
705}
706
707impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> ConvertCalendar for DateTime<A> {
708 type Converted<'a> = DateTime<Ref<'a, AnyCalendar>>;
709 #[inline]
710 fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
711 DateTime {
712 date: self.date.to_calendar(Ref(calendar)),
713 time: self.time,
714 }
715 }
716}
717
718impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>, Z: Copy> ConvertCalendar
719 for ZonedDateTime<A, Z>
720{
721 type Converted<'a> = ZonedDateTime<Ref<'a, AnyCalendar>, Z>;
722 #[inline]
723 fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
724 ZonedDateTime {
725 date: self.date.to_calendar(Ref(calendar)),
726 time: self.time,
727 zone: self.zone,
728 }
729 }
730}
731
732impl<O: TimeZoneModel> ConvertCalendar for TimeZoneInfo<O> {
733 type Converted<'a> = TimeZoneInfo<O>;
734 #[inline]
735 fn to_calendar<'a>(&self, _: &'a AnyCalendar) -> Self::Converted<'a> {
736 *self
737 }
738}
739
740pub trait InSameCalendar {
743 fn check_any_calendar_kind(
747 &self,
748 any_calendar_kind: AnyCalendarKind,
749 ) -> Result<(), MismatchedCalendarError>;
750}
751
752impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> InSameCalendar for Date<A> {
753 #[inline]
754 fn check_any_calendar_kind(
755 &self,
756 any_calendar_kind: AnyCalendarKind,
757 ) -> Result<(), MismatchedCalendarError> {
758 if self.calendar().kind() == any_calendar_kind {
759 Ok(())
760 } else {
761 Err(MismatchedCalendarError {
762 this_kind: any_calendar_kind,
763 date_kind: Some(self.calendar().kind()),
764 })
765 }
766 }
767}
768
769impl InSameCalendar for Time {
770 #[inline]
771 fn check_any_calendar_kind(&self, _: AnyCalendarKind) -> Result<(), MismatchedCalendarError> {
772 Ok(())
773 }
774}
775
776impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> InSameCalendar for DateTime<A> {
777 #[inline]
778 fn check_any_calendar_kind(
779 &self,
780 any_calendar_kind: AnyCalendarKind,
781 ) -> Result<(), MismatchedCalendarError> {
782 self.date.check_any_calendar_kind(any_calendar_kind)
783 }
784}
785
786impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>, Z> InSameCalendar for ZonedDateTime<A, Z> {
787 #[inline]
788 fn check_any_calendar_kind(
789 &self,
790 any_calendar_kind: AnyCalendarKind,
791 ) -> Result<(), MismatchedCalendarError> {
792 self.date.check_any_calendar_kind(any_calendar_kind)
793 }
794}
795
796impl InSameCalendar for UtcOffset {
797 #[inline]
798 fn check_any_calendar_kind(&self, _: AnyCalendarKind) -> Result<(), MismatchedCalendarError> {
799 Ok(())
800 }
801}
802
803impl<O: TimeZoneModel> InSameCalendar for TimeZoneInfo<O> {
804 #[inline]
805 fn check_any_calendar_kind(&self, _: AnyCalendarKind) -> Result<(), MismatchedCalendarError> {
806 Ok(())
807 }
808}
809
810pub trait InFixedCalendar<C> {}
813
814impl<C: CldrCalendar, A: AsCalendar<Calendar = C>> InFixedCalendar<C> for Date<A> {}
815
816impl<C> InFixedCalendar<C> for Time {}
817
818impl<C: CldrCalendar, A: AsCalendar<Calendar = C>> InFixedCalendar<C> for DateTime<A> {}
819
820impl<C: CldrCalendar, A: AsCalendar<Calendar = C>, Z> InFixedCalendar<C> for ZonedDateTime<A, Z> {}
821
822impl<C> InFixedCalendar<C> for UtcOffset {}
823
824impl<C, O: TimeZoneModel> InFixedCalendar<C> for TimeZoneInfo<O> {}