use alloc::string::String;
use core::marker::PhantomData;
use icu_calendar::provider::WeekDataV1Marker;
use icu_decimal::provider::DecimalSymbolsV1Marker;
use icu_plurals::provider::OrdinalV1Marker;
use icu_provider::prelude::*;
use writeable::Writeable;
use crate::provider::date_time::PatternForLengthError;
#[cfg(feature = "experimental")]
use crate::provider::date_time::UnsupportedOptionsOrDataOrPatternError;
use crate::{
calendar,
calendar::CldrCalendar,
format::zoned_datetime::FormattedZonedDateTime,
input::{DateTimeInput, TimeZoneInput},
options::DateTimeFormatterOptions,
provider::{
self,
calendar::{TimeLengthsV1Marker, TimeSymbolsV1Marker},
date_time::PatternSelector,
},
raw,
time_zone::TimeZoneFormatterOptions,
DateTimeError,
};
#[derive(Debug)]
pub struct TypedZonedDateTimeFormatter<C>(raw::ZonedDateTimeFormatter, PhantomData<C>);
impl<C: CldrCalendar> TypedZonedDateTimeFormatter<C> {
#[inline]
#[cfg(feature = "compiled_data")]
pub fn try_new(
locale: &DataLocale,
date_time_format_options: DateTimeFormatterOptions,
time_zone_format_options: TimeZoneFormatterOptions,
) -> Result<Self, DateTimeError>
where
crate::provider::Baked:
DataProvider<C::DateLengthsV1Marker> + DataProvider<C::DateSymbolsV1Marker>,
{
let patterns = PatternSelector::for_options(
&crate::provider::Baked,
calendar::load_lengths_for_cldr_calendar::<C, _>(&crate::provider::Baked, locale)?,
locale,
&date_time_format_options,
)
.map_err(|e| match e {
PatternForLengthError::Data(e) => DateTimeError::Data(e),
PatternForLengthError::Pattern(e) => DateTimeError::Pattern(e),
})?;
Ok(Self(
raw::ZonedDateTimeFormatter::try_new(
patterns,
|| {
calendar::load_symbols_for_cldr_calendar::<C, _>(
&crate::provider::Baked,
locale,
)
},
locale,
time_zone_format_options,
)?,
PhantomData,
))
}
icu_provider::gen_any_buffer_data_constructors!(
locale: include,
date_time_format_options: DateTimeFormatterOptions,
time_zone_format_options: TimeZoneFormatterOptions,
error: DateTimeError,
#[cfg(skip)]
);
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
#[inline]
pub fn try_new_unstable<P>(
provider: &P,
locale: &DataLocale,
date_time_format_options: DateTimeFormatterOptions,
time_zone_format_options: TimeZoneFormatterOptions,
) -> Result<Self, DateTimeError>
where
P: DataProvider<<C as CldrCalendar>::DateSymbolsV1Marker>
+ DataProvider<<C as CldrCalendar>::DateLengthsV1Marker>
+ DataProvider<TimeSymbolsV1Marker>
+ DataProvider<TimeLengthsV1Marker>
+ DataProvider<WeekDataV1Marker>
+ DataProvider<provider::time_zones::TimeZoneFormatsV1Marker>
+ DataProvider<provider::time_zones::ExemplarCitiesV1Marker>
+ DataProvider<provider::time_zones::MetazoneGenericNamesLongV1Marker>
+ DataProvider<provider::time_zones::MetazoneGenericNamesShortV1Marker>
+ DataProvider<provider::time_zones::MetazoneSpecificNamesLongV1Marker>
+ DataProvider<provider::time_zones::MetazoneSpecificNamesShortV1Marker>
+ DataProvider<OrdinalV1Marker>
+ DataProvider<DecimalSymbolsV1Marker>
+ ?Sized,
{
let patterns = PatternSelector::for_options(
provider,
calendar::load_lengths_for_cldr_calendar::<C, _>(provider, locale)?,
locale,
&date_time_format_options,
)
.map_err(|e| match e {
PatternForLengthError::Data(e) => DateTimeError::Data(e),
PatternForLengthError::Pattern(e) => DateTimeError::Pattern(e),
})?;
Ok(Self(
raw::ZonedDateTimeFormatter::try_new_unstable(
provider,
patterns,
|| calendar::load_symbols_for_cldr_calendar::<C, _>(provider, locale),
locale,
time_zone_format_options,
)?,
PhantomData,
))
}
#[cfg(feature = "experimental")]
#[cfg(feature = "compiled_data")]
#[inline]
pub fn try_new_experimental(
locale: &DataLocale,
date_time_format_options: DateTimeFormatterOptions,
time_zone_format_options: TimeZoneFormatterOptions,
) -> Result<Self, DateTimeError>
where
crate::provider::Baked:
DataProvider<C::DateLengthsV1Marker> + DataProvider<C::DateSymbolsV1Marker>,
{
let patterns = PatternSelector::for_options_experimental(
&crate::provider::Baked,
calendar::load_lengths_for_cldr_calendar::<C, _>(&crate::provider::Baked, locale)?,
locale,
&C::DEFAULT_BCP_47_IDENTIFIER,
&date_time_format_options,
)
.map_err(|e| match e {
UnsupportedOptionsOrDataOrPatternError::UnsupportedOptions => {
DateTimeError::UnsupportedOptions
}
UnsupportedOptionsOrDataOrPatternError::Data(e) => DateTimeError::Data(e),
UnsupportedOptionsOrDataOrPatternError::Pattern(e) => DateTimeError::Pattern(e),
})?;
Ok(Self(
raw::ZonedDateTimeFormatter::try_new(
patterns,
|| {
calendar::load_symbols_for_cldr_calendar::<C, _>(
&crate::provider::Baked,
locale,
)
},
locale,
time_zone_format_options,
)?,
PhantomData,
))
}
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new_experimental)]
#[cfg(feature = "experimental")]
#[inline]
pub fn try_new_experimental_unstable<P>(
provider: &P,
locale: &DataLocale,
date_time_format_options: DateTimeFormatterOptions,
time_zone_format_options: TimeZoneFormatterOptions,
) -> Result<Self, DateTimeError>
where
P: DataProvider<<C as CldrCalendar>::DateSymbolsV1Marker>
+ DataProvider<<C as CldrCalendar>::DateLengthsV1Marker>
+ DataProvider<TimeSymbolsV1Marker>
+ DataProvider<TimeLengthsV1Marker>
+ DataProvider<crate::provider::calendar::DateSkeletonPatternsV1Marker>
+ DataProvider<WeekDataV1Marker>
+ DataProvider<provider::time_zones::TimeZoneFormatsV1Marker>
+ DataProvider<provider::time_zones::ExemplarCitiesV1Marker>
+ DataProvider<provider::time_zones::MetazoneGenericNamesLongV1Marker>
+ DataProvider<provider::time_zones::MetazoneGenericNamesShortV1Marker>
+ DataProvider<provider::time_zones::MetazoneSpecificNamesLongV1Marker>
+ DataProvider<provider::time_zones::MetazoneSpecificNamesShortV1Marker>
+ DataProvider<OrdinalV1Marker>
+ DataProvider<DecimalSymbolsV1Marker>
+ ?Sized,
{
let patterns = PatternSelector::for_options_experimental(
provider,
calendar::load_lengths_for_cldr_calendar::<C, _>(provider, locale)?,
locale,
&C::DEFAULT_BCP_47_IDENTIFIER,
&date_time_format_options,
)
.map_err(|e| match e {
UnsupportedOptionsOrDataOrPatternError::UnsupportedOptions => {
DateTimeError::UnsupportedOptions
}
UnsupportedOptionsOrDataOrPatternError::Data(e) => DateTimeError::Data(e),
UnsupportedOptionsOrDataOrPatternError::Pattern(e) => DateTimeError::Pattern(e),
})?;
Ok(Self(
raw::ZonedDateTimeFormatter::try_new_unstable(
provider,
patterns,
|| calendar::load_symbols_for_cldr_calendar::<C, _>(provider, locale),
locale,
time_zone_format_options,
)?,
PhantomData,
))
}
#[inline]
pub fn format<'l>(
&'l self,
date: &impl DateTimeInput<Calendar = C>,
time_zone: &impl TimeZoneInput,
) -> FormattedZonedDateTime<'l> {
self.0.format(date, time_zone)
}
#[inline]
pub fn format_to_string(
&self,
date: &impl DateTimeInput<Calendar = C>,
time_zone: &impl TimeZoneInput,
) -> String {
self.format(date, time_zone).write_to_string().into_owned()
}
}