use crate::DateTimeFormatter;
use crate::DateTimeFormatterLoadError;
use crate::DateTimeFormatterPreferences;
use crate::FixedCalendarDateTimeFormatter;
#[cfg(feature = "compiled_data")]
use crate::external_loaders::ExternalLoaderCompiledData;
use crate::external_loaders::{
DecimalFormatterLoader, ExternalLoaderUnstable, FormattableAnyCalendarLoader,
};
use crate::fieldsets::enums::CompositeFieldSet;
use crate::format::DateTimeInputUnchecked;
use crate::provider::range_patterns::DatetimePatternsRangeGlueV1;
use crate::range::formatter_impl::RangeFormatterCore;
use crate::range::write::FormattedDateRange;
use crate::raw::neo::DateTimeZoneRangePatternSelectionData;
use crate::scaffold::{
AllAnyCalendarExternalDataMarkers, AllAnyCalendarFormattingDataMarkers,
AllAnyCalendarRangePatternDataMarkers, AllFixedCalendarExternalDataMarkers,
AllFixedCalendarFormattingDataMarkers, AllFixedCalendarRangePatternDataMarkers,
AllInputMarkers, CldrCalendar, ConvertCalendar, DateDataMarkers, DateInputMarkers,
DateTimeMarkers, DateTimeNamesFrom, DateTimeNamesMarker, FormattableAnyCalendarNamesLoader,
GetField, InFixedCalendar, TimeMarkers, TypedDateDataMarkers, ZoneMarkers,
};
use icu_provider::prelude::*;
#[derive(Debug)]
pub struct DateRangeFormatter<FSet: DateTimeNamesMarker> {
pub(crate) datetime_formatter: DateTimeFormatter<FSet>,
pub(crate) range_selection: DateTimeZoneRangePatternSelectionData,
}
impl<FSet: DateTimeMarkers + Clone> DateRangeFormatter<FSet>
where
FSet::D: DateDataMarkers,
FSet::T: TimeMarkers,
FSet::Z: ZoneMarkers,
FSet: GetField<CompositeFieldSet>,
{
pub(crate) fn try_new_internal<P>(
provider: &P,
external_loader: &(impl FormattableAnyCalendarLoader + DecimalFormatterLoader),
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
P: ?Sized
+ AllAnyCalendarFormattingDataMarkers<FSet>
+ AllAnyCalendarRangePatternDataMarkers<FSet>,
{
let field = field_set_with_options.get_field();
let datetime_formatter =
DateTimeFormatter::try_new_internal(provider, external_loader, prefs, field)?;
let range_selection = DateTimeZoneRangePatternSelectionData::try_new_with_skeleton(
&FormattableAnyCalendarNamesLoader::<<FSet::D as DateDataMarkers>::RangeSkel, _>::new(
provider,
&datetime_formatter.calendar,
),
&<FSet::T as TimeMarkers>::TimeRangeSkeletonPatternsV1::bind(provider),
&DatetimePatternsRangeGlueV1::bind(provider),
prefs,
field,
)
.map_err(DateTimeFormatterLoadError::Data)?;
Ok(Self {
datetime_formatter,
range_selection,
})
}
#[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable<P>(
provider: &P,
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
P: ?Sized
+ AllAnyCalendarFormattingDataMarkers<FSet>
+ AllAnyCalendarExternalDataMarkers
+ AllAnyCalendarRangePatternDataMarkers<FSet>,
{
Self::try_new_internal(
provider,
&ExternalLoaderUnstable(provider),
prefs,
field_set_with_options,
)
}
#[cfg(feature = "compiled_data")]
pub fn try_new(
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
crate::provider::Baked:
AllAnyCalendarFormattingDataMarkers<FSet> + AllAnyCalendarRangePatternDataMarkers<FSet>,
{
Self::try_new_internal(
&crate::provider::Baked,
&ExternalLoaderCompiledData,
prefs,
field_set_with_options,
)
}
#[cfg(feature = "serde")]
#[doc = icu_provider::gen_buffer_unstable_docs!(BUFFER, Self::try_new)]
pub fn try_new_with_buffer_provider<P>(
provider: &P,
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
P: BufferProvider + ?Sized,
{
use crate::provider::compat::CompatProvider;
let deser_provider = provider.as_deserializing();
let compat_provider = CompatProvider(&deser_provider, provider);
Self::try_new_unstable(&compat_provider, prefs, field_set_with_options)
}
pub fn cast_into_fset<FSet2: DateTimeNamesFrom<FSet>>(self) -> DateRangeFormatter<FSet2> {
DateRangeFormatter {
datetime_formatter: self.datetime_formatter.cast_into_fset(),
range_selection: self.range_selection,
}
}
}
impl<FSet: DateTimeMarkers + DateTimeNamesMarker> DateRangeFormatter<FSet>
where
FSet::D: DateInputMarkers,
FSet::T: TimeMarkers,
FSet::Z: ZoneMarkers,
{
pub fn format<'a, I>(&'a self, start: &I, end: &I) -> FormattedDateRange<'a>
where
I: ?Sized + ConvertCalendar,
I::Converted<'a>: Sized + AllInputMarkers<FSet>,
{
let start_cal = start.to_calendar(self.datetime_formatter.calendar.any_calendar());
let end_cal = end.to_calendar(self.datetime_formatter.calendar.any_calendar());
let start_input = DateTimeInputUnchecked::extract_from_neo_input::<
FSet::D,
FSet::T,
FSet::Z,
I::Converted<'a>,
>(&start_cal);
let end_input = DateTimeInputUnchecked::extract_from_neo_input::<
FSet::D,
FSet::T,
FSet::Z,
I::Converted<'a>,
>(&end_cal);
let core = RangeFormatterCore {
names: self.datetime_formatter.names.as_borrowed(),
selection: &self.datetime_formatter.selection,
range_selection: &self.range_selection,
};
core.format(&start_input, &end_input)
}
}
#[derive(Debug)]
pub struct FixedCalendarDateRangeFormatter<C: CldrCalendar, FSet: DateTimeNamesMarker> {
pub(crate) datetime_formatter: FixedCalendarDateTimeFormatter<C, FSet>,
pub(crate) range_selection: DateTimeZoneRangePatternSelectionData,
}
impl<C: CldrCalendar, FSet: DateTimeMarkers + Clone> FixedCalendarDateRangeFormatter<C, FSet>
where
FSet::D: TypedDateDataMarkers<C>,
FSet::T: TimeMarkers,
FSet::Z: ZoneMarkers,
FSet: GetField<CompositeFieldSet>,
{
pub(crate) fn try_new_internal<P>(
provider: &P,
external_loader: &impl DecimalFormatterLoader,
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
P: ?Sized
+ AllFixedCalendarFormattingDataMarkers<C, FSet>
+ AllFixedCalendarRangePatternDataMarkers<C, FSet>,
{
let field = field_set_with_options.get_field();
let datetime_formatter = FixedCalendarDateTimeFormatter::try_new_internal(
provider,
external_loader,
prefs,
field,
)?;
let range_selection = DateTimeZoneRangePatternSelectionData::try_new_with_skeleton(
&<FSet::D as TypedDateDataMarkers<C>>::DateRangeSkeletonPatternsV1::bind(provider),
&<FSet::T as TimeMarkers>::TimeRangeSkeletonPatternsV1::bind(provider),
&DatetimePatternsRangeGlueV1::bind(provider),
prefs,
field,
)
.map_err(DateTimeFormatterLoadError::Data)?;
Ok(Self {
datetime_formatter,
range_selection,
})
}
#[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable<P>(
provider: &P,
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
P: ?Sized
+ AllFixedCalendarFormattingDataMarkers<C, FSet>
+ AllFixedCalendarExternalDataMarkers
+ AllFixedCalendarRangePatternDataMarkers<C, FSet>,
{
Self::try_new_internal(
provider,
&ExternalLoaderUnstable(provider),
prefs,
field_set_with_options,
)
}
#[cfg(feature = "compiled_data")]
pub fn try_new(
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
crate::provider::Baked: AllFixedCalendarFormattingDataMarkers<C, FSet>
+ AllFixedCalendarRangePatternDataMarkers<C, FSet>,
{
Self::try_new_internal(
&crate::provider::Baked,
&ExternalLoaderCompiledData,
prefs,
field_set_with_options,
)
}
#[cfg(feature = "serde")]
#[doc = icu_provider::gen_buffer_unstable_docs!(BUFFER, Self::try_new)]
pub fn try_new_with_buffer_provider<P>(
provider: &P,
prefs: DateTimeFormatterPreferences,
field_set_with_options: FSet,
) -> Result<Self, DateTimeFormatterLoadError>
where
P: BufferProvider + ?Sized,
{
use crate::provider::compat::CompatProvider;
let deser_provider = provider.as_deserializing();
let compat_provider = CompatProvider(&deser_provider, provider);
Self::try_new_unstable(&compat_provider, prefs, field_set_with_options)
}
pub fn cast_into_fset<FSet2: DateTimeNamesFrom<FSet>>(
self,
) -> FixedCalendarDateRangeFormatter<C, FSet2> {
FixedCalendarDateRangeFormatter {
datetime_formatter: self.datetime_formatter.cast_into_fset(),
range_selection: self.range_selection,
}
}
}
impl<C: CldrCalendar, FSet: DateTimeMarkers + DateTimeNamesMarker>
FixedCalendarDateRangeFormatter<C, FSet>
where
FSet::D: DateInputMarkers,
FSet::T: TimeMarkers,
FSet::Z: ZoneMarkers,
{
pub fn format<'a, I>(&'a self, start: &I, end: &I) -> FormattedDateRange<'a>
where
I: ?Sized + InFixedCalendar<C> + AllInputMarkers<FSet>,
{
let start_input =
DateTimeInputUnchecked::extract_from_neo_input::<FSet::D, FSet::T, FSet::Z, I>(start);
let end_input =
DateTimeInputUnchecked::extract_from_neo_input::<FSet::D, FSet::T, FSet::Z, I>(end);
let core = RangeFormatterCore {
names: self.datetime_formatter.names.as_borrowed(),
selection: &self.datetime_formatter.selection,
range_selection: &self.range_selection,
};
core.format(&start_input, &end_input)
}
}