use crate::provider::calendar::*;
use icu_calendar::any_calendar::AnyCalendarKind;
use icu_calendar::{
buddhist::Buddhist, coptic::Coptic, ethiopian::Ethiopian, indian::Indian, japanese::Japanese,
japanese::JapaneseExtended, Gregorian,
};
use icu_locid::extensions::unicode::Value;
use icu_locid::extensions_unicode_value as value;
use icu_provider::prelude::*;
pub trait CldrCalendar {
const DEFAULT_BCP_47_IDENTIFIER: Value;
type DateSymbolsV1Marker: KeyedDataMarker<Yokeable = DateSymbolsV1<'static>>;
type DateLengthsV1Marker: KeyedDataMarker<Yokeable = DateLengthsV1<'static>>;
fn is_identifier_allowed_for_calendar(value: &Value) -> bool {
*value == Self::DEFAULT_BCP_47_IDENTIFIER
}
}
impl CldrCalendar for Gregorian {
const DEFAULT_BCP_47_IDENTIFIER: Value = value!("gregory");
type DateSymbolsV1Marker = GregorianDateSymbolsV1Marker;
type DateLengthsV1Marker = GregorianDateLengthsV1Marker;
}
impl CldrCalendar for Buddhist {
const DEFAULT_BCP_47_IDENTIFIER: Value = value!("buddhist");
type DateSymbolsV1Marker = BuddhistDateSymbolsV1Marker;
type DateLengthsV1Marker = BuddhistDateLengthsV1Marker;
}
impl CldrCalendar for Japanese {
const DEFAULT_BCP_47_IDENTIFIER: Value = value!("japanese");
type DateSymbolsV1Marker = JapaneseDateSymbolsV1Marker;
type DateLengthsV1Marker = JapaneseDateLengthsV1Marker;
}
impl CldrCalendar for JapaneseExtended {
const DEFAULT_BCP_47_IDENTIFIER: Value = value!("japanext");
type DateSymbolsV1Marker = JapaneseExtendedDateSymbolsV1Marker;
type DateLengthsV1Marker = JapaneseExtendedDateLengthsV1Marker;
}
impl CldrCalendar for Coptic {
const DEFAULT_BCP_47_IDENTIFIER: Value = value!("coptic");
type DateSymbolsV1Marker = CopticDateSymbolsV1Marker;
type DateLengthsV1Marker = CopticDateLengthsV1Marker;
}
impl CldrCalendar for Indian {
const DEFAULT_BCP_47_IDENTIFIER: Value = value!("indian");
type DateSymbolsV1Marker = IndianDateSymbolsV1Marker;
type DateLengthsV1Marker = IndianDateLengthsV1Marker;
}
impl CldrCalendar for Ethiopian {
const DEFAULT_BCP_47_IDENTIFIER: Value = value!("ethiopic");
type DateSymbolsV1Marker = EthiopianDateSymbolsV1Marker;
type DateLengthsV1Marker = EthiopianDateLengthsV1Marker;
fn is_identifier_allowed_for_calendar(value: &Value) -> bool {
*value == value!("ethiopic") || *value == value!("ethioaa")
}
}
pub(crate) fn load_lengths_for_cldr_calendar<C, P>(
provider: &P,
locale: &DataLocale,
) -> Result<DataPayload<ErasedDateLengthsV1Marker>, DataError>
where
C: CldrCalendar,
P: DataProvider<<C as CldrCalendar>::DateLengthsV1Marker> + ?Sized,
{
let payload = provider
.load(DataRequest {
locale,
metadata: Default::default(),
})?
.take_payload()?;
Ok(payload.cast())
}
pub(crate) fn load_symbols_for_cldr_calendar<C, P>(
provider: &P,
locale: &DataLocale,
) -> Result<DataPayload<ErasedDateSymbolsV1Marker>, DataError>
where
C: CldrCalendar,
P: DataProvider<<C as CldrCalendar>::DateSymbolsV1Marker> + ?Sized,
{
let payload = provider
.load(DataRequest {
locale,
metadata: Default::default(),
})?
.take_payload()?;
Ok(payload.cast())
}
pub(crate) fn load_lengths_for_any_calendar_kind<P>(
provider: &P,
locale: &DataLocale,
kind: AnyCalendarKind,
) -> Result<DataPayload<ErasedDateLengthsV1Marker>, DataError>
where
P: DataProvider<GregorianDateLengthsV1Marker>
+ DataProvider<BuddhistDateLengthsV1Marker>
+ DataProvider<JapaneseDateLengthsV1Marker>
+ DataProvider<JapaneseExtendedDateLengthsV1Marker>
+ DataProvider<CopticDateLengthsV1Marker>
+ DataProvider<IndianDateLengthsV1Marker>
+ DataProvider<EthiopianDateLengthsV1Marker>
+ ?Sized,
{
let req = DataRequest {
locale,
metadata: Default::default(),
};
let payload = match kind {
AnyCalendarKind::Gregorian => {
DataProvider::<<Gregorian as CldrCalendar>::DateLengthsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Buddhist => {
DataProvider::<<Buddhist as CldrCalendar>::DateLengthsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Japanese => {
DataProvider::<<Japanese as CldrCalendar>::DateLengthsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::JapaneseExtended => DataProvider::<
<JapaneseExtended as CldrCalendar>::DateLengthsV1Marker,
>::load(provider, req)?
.take_payload()?
.cast(),
AnyCalendarKind::Indian => {
DataProvider::<<Indian as CldrCalendar>::DateLengthsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Coptic => {
DataProvider::<<Coptic as CldrCalendar>::DateLengthsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Ethiopian => {
DataProvider::<<Ethiopian as CldrCalendar>::DateLengthsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::EthiopianAmeteAlem => {
DataProvider::<<Ethiopian as CldrCalendar>::DateLengthsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
_ => {
return Err(
DataError::custom("Don't know how to load data for specified calendar")
.with_debug_context(&kind),
)
}
};
Ok(payload)
}
pub(crate) fn load_symbols_for_any_calendar_kind<P>(
provider: &P,
locale: &DataLocale,
kind: AnyCalendarKind,
) -> Result<DataPayload<ErasedDateSymbolsV1Marker>, DataError>
where
P: DataProvider<GregorianDateSymbolsV1Marker>
+ DataProvider<BuddhistDateSymbolsV1Marker>
+ DataProvider<JapaneseDateSymbolsV1Marker>
+ DataProvider<JapaneseExtendedDateSymbolsV1Marker>
+ DataProvider<CopticDateSymbolsV1Marker>
+ DataProvider<IndianDateSymbolsV1Marker>
+ DataProvider<EthiopianDateSymbolsV1Marker>
+ ?Sized,
{
let req = DataRequest {
locale,
metadata: Default::default(),
};
let payload = match kind {
AnyCalendarKind::Gregorian => {
DataProvider::<<Gregorian as CldrCalendar>::DateSymbolsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Buddhist => {
DataProvider::<<Buddhist as CldrCalendar>::DateSymbolsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Japanese => {
DataProvider::<<Japanese as CldrCalendar>::DateSymbolsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::JapaneseExtended => DataProvider::<
<JapaneseExtended as CldrCalendar>::DateSymbolsV1Marker,
>::load(provider, req)?
.take_payload()?
.cast(),
AnyCalendarKind::Indian => {
DataProvider::<<Indian as CldrCalendar>::DateSymbolsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Coptic => {
DataProvider::<<Coptic as CldrCalendar>::DateSymbolsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::Ethiopian => {
DataProvider::<<Ethiopian as CldrCalendar>::DateSymbolsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
AnyCalendarKind::EthiopianAmeteAlem => {
DataProvider::<<Ethiopian as CldrCalendar>::DateSymbolsV1Marker>::load(provider, req)?
.take_payload()?
.cast()
}
_ => {
return Err(
DataError::custom("Don't know how to load data for specified calendar")
.with_debug_context(&kind),
)
}
};
Ok(payload)
}