use fixed_decimal::{FixedDecimal, Sign};
use icu_decimal::{
options::FixedDecimalFormatterOptions, provider::DecimalSymbolsV1Marker, FixedDecimalFormatter,
};
use icu_plurals::{provider::CardinalV1Marker, PluralRules};
use icu_provider::prelude::*;
use crate::format::FormattedRelativeTime;
use crate::provider::*;
use crate::{options::RelativeTimeFormatterOptions, RelativeTimeError};
pub struct RelativeTimeFormatter {
pub(crate) plural_rules: PluralRules,
pub(crate) rt: DataPayload<ErasedRelativeTimeFormatV1Marker>,
pub(crate) options: RelativeTimeFormatterOptions,
pub(crate) fixed_decimal_format: FixedDecimalFormatter,
}
macro_rules! constructor {
($unstable: ident, $baked: ident, $any: ident, $buffer: ident, $marker: ty) => {
#[cfg(feature = "compiled_data")]
pub fn $baked(
locale: &DataLocale,
options: RelativeTimeFormatterOptions,
) -> Result<Self, RelativeTimeError> {
let plural_rules = PluralRules::try_new_cardinal(locale)?;
let fixed_decimal_format = FixedDecimalFormatter::try_new(
locale,
FixedDecimalFormatterOptions::default(),
)?;
let rt: DataPayload<$marker> = crate::provider::Baked
.load(DataRequest {
locale,
metadata: Default::default(),
})?
.take_payload()?;
let rt = rt.cast();
Ok(RelativeTimeFormatter {
plural_rules,
options,
rt,
fixed_decimal_format,
})
}
icu_provider::gen_any_buffer_data_constructors!(
locale: include,
options: RelativeTimeFormatterOptions,
error: RelativeTimeError,
#[cfg(skip)]
functions: [
$baked,
$any,
$buffer,
$unstable,
Self,
]
);
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::$baked)]
pub fn $unstable<D>(
provider: &D,
locale: &DataLocale,
options: RelativeTimeFormatterOptions,
) -> Result<Self, RelativeTimeError>
where
D: DataProvider<CardinalV1Marker>
+ DataProvider<$marker>
+ DataProvider<DecimalSymbolsV1Marker>
+ ?Sized,
{
let plural_rules = PluralRules::try_new_cardinal_unstable(provider, locale)?;
let fixed_decimal_format = FixedDecimalFormatter::try_new_unstable(
provider,
locale,
FixedDecimalFormatterOptions::default(),
)?;
let rt: DataPayload<$marker> = provider
.load(DataRequest {
locale,
metadata: Default::default(),
})?
.take_payload()?;
let rt = rt.cast();
Ok(RelativeTimeFormatter {
plural_rules,
options,
rt,
fixed_decimal_format,
})
}
};
}
impl RelativeTimeFormatter {
constructor!(
try_new_long_second_unstable,
try_new_long_second,
try_new_long_second_with_any_provider,
try_new_long_second_with_buffer_provider,
LongSecondRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_long_minute_unstable,
try_new_long_minute,
try_new_long_minute_with_any_provider,
try_new_long_minute_with_buffer_provider,
LongMinuteRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_long_hour_unstable,
try_new_long_hour,
try_new_long_hour_with_any_provider,
try_new_long_hour_with_buffer_provider,
LongHourRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_long_day_unstable,
try_new_long_day,
try_new_long_day_with_any_provider,
try_new_long_day_with_buffer_provider,
LongDayRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_long_week_unstable,
try_new_long_week,
try_new_long_week_with_any_provider,
try_new_long_week_with_buffer_provider,
LongWeekRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_long_month_unstable,
try_new_long_month,
try_new_long_month_with_any_provider,
try_new_long_month_with_buffer_provider,
LongMonthRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_long_quarter_unstable,
try_new_long_quarter,
try_new_long_quarter_with_any_provider,
try_new_long_quarter_with_buffer_provider,
LongQuarterRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_long_year_unstable,
try_new_long_year,
try_new_long_year_with_any_provider,
try_new_long_year_with_buffer_provider,
LongYearRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_second_unstable,
try_new_short_second,
try_new_short_second_with_any_provider,
try_new_short_second_with_buffer_provider,
ShortSecondRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_minute_unstable,
try_new_short_minute,
try_new_short_minute_with_any_provider,
try_new_short_minute_with_buffer_provider,
ShortMinuteRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_hour_unstable,
try_new_short_hour,
try_new_short_hour_with_any_provider,
try_new_short_hour_with_buffer_provider,
ShortHourRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_day_unstable,
try_new_short_day,
try_new_short_day_with_any_provider,
try_new_short_day_with_buffer_provider,
ShortDayRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_week_unstable,
try_new_short_week,
try_new_short_week_with_any_provider,
try_new_short_week_with_buffer_provider,
ShortWeekRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_month_unstable,
try_new_short_month,
try_new_short_month_with_any_provider,
try_new_short_month_with_buffer_provider,
ShortMonthRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_quarter_unstable,
try_new_short_quarter,
try_new_short_quarter_with_any_provider,
try_new_short_quarter_with_buffer_provider,
ShortQuarterRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_short_year_unstable,
try_new_short_year,
try_new_short_year_with_any_provider,
try_new_short_year_with_buffer_provider,
ShortYearRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_second_unstable,
try_new_narrow_second,
try_new_narrow_second_with_any_provider,
try_new_narrow_second_with_buffer_provider,
NarrowSecondRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_minute_unstable,
try_new_narrow_minute,
try_new_narrow_minute_with_any_provider,
try_new_narrow_minute_with_buffer_provider,
NarrowMinuteRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_hour_unstable,
try_new_narrow_hour,
try_new_narrow_hour_with_any_provider,
try_new_narrow_hour_with_buffer_provider,
NarrowHourRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_day_unstable,
try_new_narrow_day,
try_new_narrow_day_with_any_provider,
try_new_narrow_day_with_buffer_provider,
NarrowDayRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_week_unstable,
try_new_narrow_week,
try_new_narrow_week_with_any_provider,
try_new_narrow_week_with_buffer_provider,
NarrowWeekRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_month_unstable,
try_new_narrow_month,
try_new_narrow_month_with_any_provider,
try_new_narrow_month_with_buffer_provider,
NarrowMonthRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_quarter_unstable,
try_new_narrow_quarter,
try_new_narrow_quarter_with_any_provider,
try_new_narrow_quarter_with_buffer_provider,
NarrowQuarterRelativeTimeFormatDataV1Marker
);
constructor!(
try_new_narrow_year_unstable,
try_new_narrow_year,
try_new_narrow_year_with_any_provider,
try_new_narrow_year_with_buffer_provider,
NarrowYearRelativeTimeFormatDataV1Marker
);
pub fn format(&self, value: FixedDecimal) -> FormattedRelativeTime<'_> {
let is_negative = value.sign() == Sign::Negative;
FormattedRelativeTime {
options: &self.options,
formatter: self,
value: value.with_sign(Sign::None),
is_negative,
}
}
}