1use crate::provider::{neo::*, *};
8use crate::scaffold::UnstableSealed;
9use crate::{DateTimeFormatterPreferences, MismatchedCalendarError};
10use core::marker::PhantomData;
11use icu_calendar::cal::Roc;
12use icu_calendar::cal::{self, Chinese};
13use icu_calendar::cal::{
14    Buddhist, Coptic, Dangi, Ethiopian, Gregorian, Hebrew, HijriSimulated, HijriTabular,
15    HijriUmmAlQura, Indian, Japanese, JapaneseExtended, Persian,
16};
17use icu_calendar::{AnyCalendar, AnyCalendarKind, AsCalendar, Date, IntoAnyCalendar, Ref};
18use icu_provider::marker::NeverMarker;
19use icu_provider::prelude::*;
20use icu_time::{
21    zone::{models::TimeZoneModel, UtcOffset},
22    DateTime, Time, TimeZoneInfo, ZonedDateTime,
23};
24
25pub trait CldrCalendar: UnstableSealed {
35    type YearNamesV1: DataMarker<DataStruct = YearNames<'static>>;
37
38    type MonthNamesV1: DataMarker<DataStruct = MonthNames<'static>>;
40
41    type SkeletaV1: DataMarker<DataStruct = PackedPatterns<'static>>;
43}
44
45impl CldrCalendar for () {
46    type YearNamesV1 = NeverMarker<YearNames<'static>>;
47    type MonthNamesV1 = NeverMarker<MonthNames<'static>>;
48    type SkeletaV1 = NeverMarker<PackedPatterns<'static>>;
49}
50
51impl CldrCalendar for Buddhist {
52    type YearNamesV1 = DatetimeNamesYearBuddhistV1;
53    type MonthNamesV1 = DatetimeNamesMonthBuddhistV1;
54    type SkeletaV1 = DatetimePatternsDateBuddhistV1;
55}
56
57impl CldrCalendar for Chinese {
58    type YearNamesV1 = DatetimeNamesYearChineseV1;
59    type MonthNamesV1 = DatetimeNamesMonthChineseV1;
60    type SkeletaV1 = DatetimePatternsDateChineseV1;
61}
62
63impl CldrCalendar for Coptic {
64    type YearNamesV1 = DatetimeNamesYearCopticV1;
65    type MonthNamesV1 = DatetimeNamesMonthCopticV1;
66    type SkeletaV1 = DatetimePatternsDateCopticV1;
67}
68
69impl CldrCalendar for Dangi {
70    type YearNamesV1 = DatetimeNamesYearDangiV1;
71    type MonthNamesV1 = DatetimeNamesMonthDangiV1;
72    type SkeletaV1 = DatetimePatternsDateDangiV1;
73}
74
75impl CldrCalendar for Ethiopian {
76    type YearNamesV1 = DatetimeNamesYearEthiopianV1;
77    type MonthNamesV1 = DatetimeNamesMonthEthiopianV1;
78    type SkeletaV1 = DatetimePatternsDateEthiopianV1;
79}
80
81impl CldrCalendar for Gregorian {
82    type YearNamesV1 = DatetimeNamesYearGregorianV1;
83    type MonthNamesV1 = DatetimeNamesMonthGregorianV1;
84    type SkeletaV1 = DatetimePatternsDateGregorianV1;
85}
86
87impl CldrCalendar for Hebrew {
88    type YearNamesV1 = DatetimeNamesYearHebrewV1;
89    type MonthNamesV1 = DatetimeNamesMonthHebrewV1;
90    type SkeletaV1 = DatetimePatternsDateHebrewV1;
91}
92
93impl CldrCalendar for Indian {
94    type YearNamesV1 = DatetimeNamesYearIndianV1;
95    type MonthNamesV1 = DatetimeNamesMonthIndianV1;
96    type SkeletaV1 = DatetimePatternsDateIndianV1;
97}
98
99impl CldrCalendar for HijriTabular {
100    type YearNamesV1 = DatetimeNamesYearHijriV1;
101    type MonthNamesV1 = DatetimeNamesMonthHijriV1;
102    type SkeletaV1 = DatetimePatternsDateHijriV1;
103}
104
105impl CldrCalendar for HijriSimulated {
106    type YearNamesV1 = DatetimeNamesYearHijriV1;
107    type MonthNamesV1 = DatetimeNamesMonthHijriV1;
108    type SkeletaV1 = DatetimePatternsDateHijriV1;
109}
110
111impl CldrCalendar for HijriUmmAlQura {
112    type YearNamesV1 = DatetimeNamesYearHijriV1;
113    type MonthNamesV1 = DatetimeNamesMonthHijriV1;
114    type SkeletaV1 = DatetimePatternsDateHijriV1;
115}
116
117impl CldrCalendar for Japanese {
118    type YearNamesV1 = DatetimeNamesYearJapaneseV1;
119    type MonthNamesV1 = DatetimeNamesMonthJapaneseV1;
120    type SkeletaV1 = DatetimePatternsDateJapaneseV1;
121}
122
123impl CldrCalendar for JapaneseExtended {
124    type YearNamesV1 = DatetimeNamesYearJapanextV1;
125    type MonthNamesV1 = DatetimeNamesMonthJapanextV1;
126    type SkeletaV1 = DatetimePatternsDateJapanextV1;
127}
128
129impl CldrCalendar for Persian {
130    type YearNamesV1 = DatetimeNamesYearPersianV1;
131    type MonthNamesV1 = DatetimeNamesMonthPersianV1;
132    type SkeletaV1 = DatetimePatternsDatePersianV1;
133}
134
135impl CldrCalendar for Roc {
136    type YearNamesV1 = DatetimeNamesYearRocV1;
137    type MonthNamesV1 = DatetimeNamesMonthRocV1;
138    type SkeletaV1 = DatetimePatternsDateRocV1;
139}
140
141impl UnstableSealed for () {}
142impl UnstableSealed for Buddhist {}
143impl UnstableSealed for Chinese {}
144impl UnstableSealed for Coptic {}
145impl UnstableSealed for Dangi {}
146impl UnstableSealed for Ethiopian {}
147impl UnstableSealed for Gregorian {}
148impl UnstableSealed for Hebrew {}
149impl UnstableSealed for Indian {}
150impl UnstableSealed for HijriTabular {}
151impl UnstableSealed for HijriSimulated {}
152impl UnstableSealed for HijriUmmAlQura {}
153impl UnstableSealed for Japanese {}
154impl UnstableSealed for JapaneseExtended {}
155impl UnstableSealed for Persian {}
156impl UnstableSealed for Roc {}
157
158pub trait CalMarkers<M>: UnstableSealed
170where
171    M: DynamicDataMarker,
172{
173    type Buddhist: DataMarker<DataStruct = M::DataStruct>;
175    type Chinese: DataMarker<DataStruct = M::DataStruct>;
177    type Coptic: DataMarker<DataStruct = M::DataStruct>;
179    type Dangi: DataMarker<DataStruct = M::DataStruct>;
181    type Ethiopian: DataMarker<DataStruct = M::DataStruct>;
183    type Gregorian: DataMarker<DataStruct = M::DataStruct>;
185    type Hebrew: DataMarker<DataStruct = M::DataStruct>;
187    type Indian: DataMarker<DataStruct = M::DataStruct>;
189    type Hijri: DataMarker<DataStruct = M::DataStruct>;
191    type Japanese: DataMarker<DataStruct = M::DataStruct>;
193    type Persian: DataMarker<DataStruct = M::DataStruct>;
195    type Roc: DataMarker<DataStruct = M::DataStruct>;
197}
198
199#[derive(Debug)]
201#[allow(clippy::exhaustive_enums)] pub enum FullDataCalMarkers {}
203
204impl UnstableSealed for FullDataCalMarkers {}
205
206#[derive(Debug)]
208#[allow(clippy::exhaustive_enums)] pub enum NoDataCalMarkers {}
210
211impl UnstableSealed for NoDataCalMarkers {}
212
213impl<M> CalMarkers<M> for NoDataCalMarkers
214where
215    M: DynamicDataMarker,
216{
217    type Buddhist = NeverMarker<M::DataStruct>;
218    type Chinese = NeverMarker<M::DataStruct>;
219    type Coptic = NeverMarker<M::DataStruct>;
220    type Dangi = NeverMarker<M::DataStruct>;
221    type Ethiopian = NeverMarker<M::DataStruct>;
222    type Gregorian = NeverMarker<M::DataStruct>;
223    type Hebrew = NeverMarker<M::DataStruct>;
224    type Indian = NeverMarker<M::DataStruct>;
225    type Hijri = NeverMarker<M::DataStruct>;
226    type Japanese = NeverMarker<M::DataStruct>;
227    type Persian = NeverMarker<M::DataStruct>;
228    type Roc = NeverMarker<M::DataStruct>;
229}
230
231pub trait IntoFormattableAnyCalendar: CldrCalendar + IntoAnyCalendar {}
235
236impl IntoFormattableAnyCalendar for Buddhist {}
238impl IntoFormattableAnyCalendar for Chinese {}
239impl IntoFormattableAnyCalendar for Coptic {}
240impl IntoFormattableAnyCalendar for Dangi {}
241impl IntoFormattableAnyCalendar for Ethiopian {}
242impl IntoFormattableAnyCalendar for Gregorian {}
243impl IntoFormattableAnyCalendar for Hebrew {}
244impl IntoFormattableAnyCalendar for Indian {}
245impl IntoFormattableAnyCalendar for HijriTabular {}
246impl IntoFormattableAnyCalendar for HijriSimulated {}
247impl IntoFormattableAnyCalendar for HijriUmmAlQura {}
248impl IntoFormattableAnyCalendar for Japanese {}
249impl IntoFormattableAnyCalendar for Persian {}
251impl IntoFormattableAnyCalendar for Roc {}
252
253#[derive(Debug, Clone, Copy)]
255pub(crate) enum FormattableAnyCalendarKind {
256    Buddhist,
257    Chinese,
258    Coptic,
259    Dangi,
260    Ethiopian,
261    EthiopianAmeteAlem,
262    Gregorian,
263    Hebrew,
264    Indian,
265    HijriTabularTypeIIFriday,
266    HijriTabularTypeIIThursday,
268    HijriUmmAlQura,
269    Japanese,
270    Persian,
272    Roc,
273}
274
275impl FormattableAnyCalendarKind {
276    pub(crate) fn try_from_any_calendar_kind(kind: AnyCalendarKind) -> Option<Self> {
277        use AnyCalendarKind::*;
278        let res = match kind {
279            Buddhist => Self::Buddhist,
280            Chinese => Self::Chinese,
281            Coptic => Self::Coptic,
282            Dangi => Self::Dangi,
283            Ethiopian => Self::Ethiopian,
284            EthiopianAmeteAlem => Self::EthiopianAmeteAlem,
285            Gregorian => Self::Gregorian,
286            Hebrew => Self::Hebrew,
287            Indian => Self::Indian,
288            HijriTabularTypeIIFriday => Self::HijriTabularTypeIIFriday,
289            HijriSimulatedMecca => return None,
290            HijriTabularTypeIIThursday => Self::HijriTabularTypeIIThursday,
291            HijriUmmAlQura => Self::HijriUmmAlQura,
292            Iso => return None,
293            Japanese => Self::Japanese,
294            JapaneseExtended => return None,
295            Persian => Self::Persian,
296            Roc => Self::Roc,
297            _ => {
298                debug_assert!(false, "cross-crate exhaustive match");
299                return None;
300            }
301        };
302        Some(res)
303    }
304
305    pub(crate) fn from_preferences(mut prefs: DateTimeFormatterPreferences) -> Self {
306        if let Some(algo) = prefs.calendar_algorithm {
307            if let Ok(kind) = AnyCalendarKind::try_from(algo) {
308                if let Some(res) = Self::try_from_any_calendar_kind(kind) {
309                    return res;
310                }
311            }
312        }
313        prefs.calendar_algorithm = None;
317        let kind = AnyCalendarKind::new((&prefs).into());
318        match Self::try_from_any_calendar_kind(kind) {
319            Some(res) => res,
320            None => {
321                debug_assert!(false, "all locale-default calendars are supported");
322                FormattableAnyCalendarKind::Coptic
324            }
325        }
326    }
327}
328
329#[derive(Debug, Clone)]
331pub(crate) struct FormattableAnyCalendar {
332    any_calendar: AnyCalendar,
333    kind: FormattableAnyCalendarKind,
334}
335
336impl FormattableAnyCalendar {
337    pub(crate) fn from_calendar(calendar: impl IntoFormattableAnyCalendar) -> Self {
338        let any_calendar = calendar.to_any();
339        let kind = any_calendar.kind();
340        let kind = FormattableAnyCalendarKind::try_from_any_calendar_kind(any_calendar.kind())
341            .unwrap_or_else(|| {
342                debug_assert!(false, "{kind:?} is not a FormattableAnyCalendarKind");
343                FormattableAnyCalendarKind::Coptic
344            });
345        Self { any_calendar, kind }
346    }
347
348    pub(crate) fn try_from_any_calendar(any_calendar: AnyCalendar) -> Option<Self> {
349        let kind = FormattableAnyCalendarKind::try_from_any_calendar_kind(any_calendar.kind())?;
350        Some(Self { any_calendar, kind })
351    }
352
353    pub(crate) fn kind(&self) -> FormattableAnyCalendarKind {
354        self.kind
355    }
356
357    #[cfg(feature = "compiled_data")]
358    pub(crate) fn try_new(kind: FormattableAnyCalendarKind) -> Result<Self, DataError> {
359        use FormattableAnyCalendarKind::*;
360        let any_calendar = match kind {
361            Buddhist => AnyCalendar::Buddhist(cal::Buddhist),
362            Chinese => AnyCalendar::Chinese(cal::Chinese::new()),
363            Coptic => AnyCalendar::Coptic(cal::Coptic),
364            Dangi => AnyCalendar::Dangi(cal::Dangi::new()),
365            Ethiopian => AnyCalendar::Ethiopian(cal::Ethiopian::new()),
366            EthiopianAmeteAlem => AnyCalendar::Ethiopian(cal::Ethiopian::new_with_era_style(
367                cal::EthiopianEraStyle::AmeteAlem,
368            )),
369            Gregorian => AnyCalendar::Gregorian(cal::Gregorian),
370            Hebrew => AnyCalendar::Hebrew(cal::Hebrew),
371            Indian => AnyCalendar::Indian(cal::Indian),
372            HijriTabularTypeIIFriday => AnyCalendar::HijriTabular(cal::HijriTabular::new(
373                cal::HijriTabularLeapYears::TypeII,
374                cal::HijriTabularEpoch::Friday,
375            )),
376            HijriTabularTypeIIThursday => AnyCalendar::HijriTabular(cal::HijriTabular::new(
377                cal::HijriTabularLeapYears::TypeII,
378                cal::HijriTabularEpoch::Thursday,
379            )),
380            HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(cal::HijriUmmAlQura::new()),
381            Japanese => AnyCalendar::Japanese(cal::Japanese::new()),
382            Persian => AnyCalendar::Persian(cal::Persian),
383            Roc => AnyCalendar::Roc(cal::Roc),
384        };
385        Ok(Self { any_calendar, kind })
386    }
387
388    #[cfg(feature = "serde")]
389    pub(crate) fn try_new_with_buffer_provider<P>(
390        provider: &P,
391        kind: FormattableAnyCalendarKind,
392    ) -> Result<Self, DataError>
393    where
394        P: ?Sized + BufferProvider,
395    {
396        use FormattableAnyCalendarKind::*;
397        let any_calendar = match kind {
398            Buddhist => AnyCalendar::Buddhist(cal::Buddhist),
399            Chinese => AnyCalendar::Chinese(cal::Chinese::try_new_with_buffer_provider(provider)?),
400            Coptic => AnyCalendar::Coptic(cal::Coptic),
401            Dangi => AnyCalendar::Dangi(cal::Dangi::try_new_with_buffer_provider(provider)?),
402            Ethiopian => AnyCalendar::Ethiopian(cal::Ethiopian::new()),
403            EthiopianAmeteAlem => AnyCalendar::Ethiopian(cal::Ethiopian::new_with_era_style(
404                cal::EthiopianEraStyle::AmeteAlem,
405            )),
406            Gregorian => AnyCalendar::Gregorian(cal::Gregorian),
407            Hebrew => AnyCalendar::Hebrew(cal::Hebrew),
408            Indian => AnyCalendar::Indian(cal::Indian),
409            HijriTabularTypeIIFriday => AnyCalendar::HijriTabular(cal::HijriTabular::new(
410                cal::HijriTabularLeapYears::TypeII,
411                cal::HijriTabularEpoch::Friday,
412            )),
413            HijriTabularTypeIIThursday => AnyCalendar::HijriTabular(cal::HijriTabular::new(
414                cal::HijriTabularLeapYears::TypeII,
415                cal::HijriTabularEpoch::Thursday,
416            )),
417            HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(cal::HijriUmmAlQura::new()),
418            Japanese => {
419                AnyCalendar::Japanese(cal::Japanese::try_new_with_buffer_provider(provider)?)
420            }
421            Persian => AnyCalendar::Persian(cal::Persian),
422            Roc => AnyCalendar::Roc(cal::Roc),
423        };
424        Ok(Self { any_calendar, kind })
425    }
426
427    pub(crate) fn try_new_unstable<P>(
428        provider: &P,
429        kind: FormattableAnyCalendarKind,
430    ) -> Result<Self, DataError>
431    where
432        P: ?Sized
433            + DataProvider<icu_calendar::provider::CalendarJapaneseModernV1>
434            + DataProvider<icu_calendar::provider::CalendarChineseV1>
435            + DataProvider<icu_calendar::provider::CalendarDangiV1>,
436    {
437        use FormattableAnyCalendarKind::*;
438        let any_calendar = match kind {
439            Buddhist => AnyCalendar::Buddhist(cal::Buddhist),
440            Chinese => AnyCalendar::Chinese(cal::Chinese::try_new_unstable(provider)?),
441            Coptic => AnyCalendar::Coptic(cal::Coptic),
442            Dangi => AnyCalendar::Dangi(cal::Dangi::try_new_unstable(provider)?),
443            Ethiopian => AnyCalendar::Ethiopian(cal::Ethiopian::new()),
444            EthiopianAmeteAlem => AnyCalendar::Ethiopian(cal::Ethiopian::new_with_era_style(
445                cal::EthiopianEraStyle::AmeteAlem,
446            )),
447            Gregorian => AnyCalendar::Gregorian(cal::Gregorian),
448            Hebrew => AnyCalendar::Hebrew(cal::Hebrew),
449            Indian => AnyCalendar::Indian(cal::Indian),
450            HijriTabularTypeIIFriday => AnyCalendar::HijriTabular(cal::HijriTabular::new(
451                cal::HijriTabularLeapYears::TypeII,
452                cal::HijriTabularEpoch::Friday,
453            )),
454            HijriTabularTypeIIThursday => AnyCalendar::HijriTabular(cal::HijriTabular::new(
455                cal::HijriTabularLeapYears::TypeII,
456                cal::HijriTabularEpoch::Thursday,
457            )),
458            HijriUmmAlQura => AnyCalendar::HijriUmmAlQura(cal::HijriUmmAlQura::new()),
459            Japanese => AnyCalendar::Japanese(cal::Japanese::try_new_unstable(provider)?),
460            Persian => AnyCalendar::Persian(cal::Persian),
461            Roc => AnyCalendar::Roc(cal::Roc),
462        };
463        Ok(Self { any_calendar, kind })
464    }
465
466    pub(crate) fn into_untagged(self) -> UntaggedFormattableAnyCalendar {
467        UntaggedFormattableAnyCalendar {
468            any_calendar: self.any_calendar,
469        }
470    }
471}
472
473#[derive(Debug, Clone)]
474pub(crate) struct UntaggedFormattableAnyCalendar {
475    any_calendar: AnyCalendar,
477}
478
479impl UntaggedFormattableAnyCalendar {
481    pub(crate) fn into_tagged(self) -> FormattableAnyCalendar {
482        let kind = FormattableAnyCalendarKind::try_from_any_calendar_kind(self.any_calendar.kind())
483            .unwrap_or_else(|| {
484                debug_assert!(false, "unreachable by invariant");
485                FormattableAnyCalendarKind::Coptic
487            });
488        FormattableAnyCalendar {
489            any_calendar: self.any_calendar,
490            kind,
491        }
492    }
493
494    pub(crate) fn any_calendar(&self) -> &AnyCalendar {
495        &self.any_calendar
496    }
497
498    pub(crate) fn take_any_calendar(self) -> AnyCalendar {
499        self.any_calendar
500    }
501}
502
503pub(crate) struct FormattableAnyCalendarNamesLoader<H, P> {
504    provider: P,
505    kind: FormattableAnyCalendarKind,
506    _helper: PhantomData<H>,
507}
508
509impl<H, P> FormattableAnyCalendarNamesLoader<H, P> {
510    pub(crate) fn new(provider: P, kind: FormattableAnyCalendarKind) -> Self {
511        Self {
512            provider,
513            kind,
514            _helper: PhantomData,
515        }
516    }
517}
518
519impl<M, H, P> BoundDataProvider<M> for FormattableAnyCalendarNamesLoader<H, P>
520where
521    M: DynamicDataMarker,
522    H: CalMarkers<M>,
523    P: Sized
524        + DataProvider<H::Buddhist>
525        + DataProvider<H::Chinese>
526        + DataProvider<H::Coptic>
527        + DataProvider<H::Dangi>
528        + DataProvider<H::Ethiopian>
529        + DataProvider<H::Gregorian>
530        + DataProvider<H::Hebrew>
531        + DataProvider<H::Indian>
532        + DataProvider<H::Hijri>
533        + DataProvider<H::Japanese>
534        + DataProvider<H::Persian>
535        + DataProvider<H::Roc>,
536{
537    fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
538        use FormattableAnyCalendarKind::*;
539        let p = &self.provider;
540        match self.kind {
541            Buddhist => H::Buddhist::bind(p).load_bound(req),
542            Chinese => H::Chinese::bind(p).load_bound(req),
543            Coptic => H::Coptic::bind(p).load_bound(req),
544            Dangi => H::Dangi::bind(p).load_bound(req),
545            Ethiopian | EthiopianAmeteAlem => H::Ethiopian::bind(p).load_bound(req),
546            Gregorian => H::Gregorian::bind(p).load_bound(req),
547            Hebrew => H::Hebrew::bind(p).load_bound(req),
548            Indian => H::Indian::bind(p).load_bound(req),
549            HijriTabularTypeIIFriday | HijriTabularTypeIIThursday | HijriUmmAlQura => {
550                H::Hijri::bind(p).load_bound(req)
551            }
552            Japanese => H::Japanese::bind(p).load_bound(req),
553            Persian => H::Persian::bind(p).load_bound(req),
554            Roc => H::Roc::bind(p).load_bound(req),
555        }
556    }
557    fn bound_marker(&self) -> DataMarkerInfo {
558        use FormattableAnyCalendarKind::*;
559        match self.kind {
560            Buddhist => H::Buddhist::INFO,
561            Chinese => H::Chinese::INFO,
562            Coptic => H::Coptic::INFO,
563            Dangi => H::Dangi::INFO,
564            Ethiopian | EthiopianAmeteAlem => H::Ethiopian::INFO,
565            Gregorian => H::Gregorian::INFO,
566            Hebrew => H::Hebrew::INFO,
567            Indian => H::Indian::INFO,
568            HijriTabularTypeIIFriday | HijriTabularTypeIIThursday | HijriUmmAlQura => {
569                H::Hijri::INFO
570            }
571            Japanese => H::Japanese::INFO,
572            Persian => H::Persian::INFO,
573            Roc => H::Roc::INFO,
574        }
575    }
576}
577
578impl CalMarkers<YearNamesV1> for FullDataCalMarkers {
579    type Buddhist = <Buddhist as CldrCalendar>::YearNamesV1;
580    type Chinese = <Chinese as CldrCalendar>::YearNamesV1;
581    type Coptic = <Coptic as CldrCalendar>::YearNamesV1;
582    type Dangi = <Dangi as CldrCalendar>::YearNamesV1;
583    type Ethiopian = <Ethiopian as CldrCalendar>::YearNamesV1;
584    type Gregorian = <Gregorian as CldrCalendar>::YearNamesV1;
585    type Hebrew = <Hebrew as CldrCalendar>::YearNamesV1;
586    type Indian = <Indian as CldrCalendar>::YearNamesV1;
587    type Hijri = <HijriUmmAlQura as CldrCalendar>::YearNamesV1;
588    type Japanese = <Japanese as CldrCalendar>::YearNamesV1;
589    type Persian = <Persian as CldrCalendar>::YearNamesV1;
590    type Roc = <Roc as CldrCalendar>::YearNamesV1;
591}
592
593impl CalMarkers<MonthNamesV1> for FullDataCalMarkers {
594    type Buddhist = <Buddhist as CldrCalendar>::MonthNamesV1;
595    type Chinese = <Chinese as CldrCalendar>::MonthNamesV1;
596    type Coptic = <Coptic as CldrCalendar>::MonthNamesV1;
597    type Dangi = <Dangi as CldrCalendar>::MonthNamesV1;
598    type Ethiopian = <Ethiopian as CldrCalendar>::MonthNamesV1;
599    type Gregorian = <Gregorian as CldrCalendar>::MonthNamesV1;
600    type Hebrew = <Hebrew as CldrCalendar>::MonthNamesV1;
601    type Indian = <Indian as CldrCalendar>::MonthNamesV1;
602    type Hijri = <HijriUmmAlQura as CldrCalendar>::MonthNamesV1;
603    type Japanese = <Japanese as CldrCalendar>::MonthNamesV1;
604    type Persian = <Persian as CldrCalendar>::MonthNamesV1;
605    type Roc = <Roc as CldrCalendar>::MonthNamesV1;
606}
607
608impl CalMarkers<ErasedPackedPatterns> for FullDataCalMarkers {
609    type Buddhist = <Buddhist as CldrCalendar>::SkeletaV1;
610    type Chinese = <Chinese as CldrCalendar>::SkeletaV1;
611    type Coptic = <Coptic as CldrCalendar>::SkeletaV1;
612    type Dangi = <Dangi as CldrCalendar>::SkeletaV1;
613    type Ethiopian = <Ethiopian as CldrCalendar>::SkeletaV1;
614    type Gregorian = <Gregorian as CldrCalendar>::SkeletaV1;
615    type Hebrew = <Hebrew as CldrCalendar>::SkeletaV1;
616    type Indian = <Indian as CldrCalendar>::SkeletaV1;
617    type Hijri = <HijriUmmAlQura as CldrCalendar>::SkeletaV1;
618    type Japanese = <Japanese as CldrCalendar>::SkeletaV1;
619    type Persian = <Persian as CldrCalendar>::SkeletaV1;
620    type Roc = <Roc as CldrCalendar>::SkeletaV1;
621}
622
623pub trait ConvertCalendar {
626    type Converted<'a>: Sized;
628    fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a>;
630}
631
632impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> ConvertCalendar for Date<A> {
633    type Converted<'a> = Date<Ref<'a, AnyCalendar>>;
634    #[inline]
635    fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
636        self.to_calendar(Ref(calendar))
637    }
638}
639
640impl ConvertCalendar for Time {
641    type Converted<'a> = Time;
642    #[inline]
643    fn to_calendar<'a>(&self, _: &'a AnyCalendar) -> Self::Converted<'a> {
644        *self
645    }
646}
647
648impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> ConvertCalendar for DateTime<A> {
649    type Converted<'a> = DateTime<Ref<'a, AnyCalendar>>;
650    #[inline]
651    fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
652        DateTime {
653            date: self.date.to_calendar(Ref(calendar)),
654            time: self.time,
655        }
656    }
657}
658
659impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>, Z: Copy> ConvertCalendar
660    for ZonedDateTime<A, Z>
661{
662    type Converted<'a> = ZonedDateTime<Ref<'a, AnyCalendar>, Z>;
663    #[inline]
664    fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
665        ZonedDateTime {
666            date: self.date.to_calendar(Ref(calendar)),
667            time: self.time,
668            zone: self.zone,
669        }
670    }
671}
672
673impl<O: TimeZoneModel> ConvertCalendar for TimeZoneInfo<O> {
674    type Converted<'a> = TimeZoneInfo<O>;
675    #[inline]
676    fn to_calendar<'a>(&self, _: &'a AnyCalendar) -> Self::Converted<'a> {
677        *self
678    }
679}
680
681pub trait InSameCalendar {
684    fn check_any_calendar_kind(
688        &self,
689        any_calendar_kind: AnyCalendarKind,
690    ) -> Result<(), MismatchedCalendarError>;
691}
692
693impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> InSameCalendar for Date<A> {
694    #[inline]
695    fn check_any_calendar_kind(
696        &self,
697        any_calendar_kind: AnyCalendarKind,
698    ) -> Result<(), MismatchedCalendarError> {
699        if self.calendar().kind() == any_calendar_kind {
700            Ok(())
701        } else {
702            Err(MismatchedCalendarError {
703                this_kind: any_calendar_kind,
704                date_kind: Some(self.calendar().kind()),
705            })
706        }
707    }
708}
709
710impl InSameCalendar for Time {
711    #[inline]
712    fn check_any_calendar_kind(&self, _: AnyCalendarKind) -> Result<(), MismatchedCalendarError> {
713        Ok(())
714    }
715}
716
717impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> InSameCalendar for DateTime<A> {
718    #[inline]
719    fn check_any_calendar_kind(
720        &self,
721        any_calendar_kind: AnyCalendarKind,
722    ) -> Result<(), MismatchedCalendarError> {
723        self.date.check_any_calendar_kind(any_calendar_kind)
724    }
725}
726
727impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>, Z> InSameCalendar for ZonedDateTime<A, Z> {
728    #[inline]
729    fn check_any_calendar_kind(
730        &self,
731        any_calendar_kind: AnyCalendarKind,
732    ) -> Result<(), MismatchedCalendarError> {
733        self.date.check_any_calendar_kind(any_calendar_kind)
734    }
735}
736
737impl InSameCalendar for UtcOffset {
738    #[inline]
739    fn check_any_calendar_kind(&self, _: AnyCalendarKind) -> Result<(), MismatchedCalendarError> {
740        Ok(())
741    }
742}
743
744impl<O: TimeZoneModel> InSameCalendar for TimeZoneInfo<O> {
745    #[inline]
746    fn check_any_calendar_kind(&self, _: AnyCalendarKind) -> Result<(), MismatchedCalendarError> {
747        Ok(())
748    }
749}
750
751pub trait InFixedCalendar<C> {}
754
755impl<C: CldrCalendar, A: AsCalendar<Calendar = C>> InFixedCalendar<C> for Date<A> {}
756
757impl<C> InFixedCalendar<C> for Time {}
758
759impl<C: CldrCalendar, A: AsCalendar<Calendar = C>> InFixedCalendar<C> for DateTime<A> {}
760
761impl<C: CldrCalendar, A: AsCalendar<Calendar = C>, Z> InFixedCalendar<C> for ZonedDateTime<A, Z> {}
762
763impl<C> InFixedCalendar<C> for UtcOffset {}
764
765impl<C, O: TimeZoneModel> InFixedCalendar<C> for TimeZoneInfo<O> {}