use alloc::fmt::Write;
use fixed_decimal::FixedDecimal;
use writeable::Writeable;
use crate::relativetime::{
options::{Numeric, RelativeTimeFormatterOptions},
relativetime::RelativeTimeFormatter,
};
pub mod parts {
use writeable::Part;
pub const LITERAL: Part = Part {
category: "relativetime",
value: "literal",
};
}
pub struct FormattedRelativeTime<'a> {
pub(crate) formatter: &'a RelativeTimeFormatter,
pub(crate) options: &'a RelativeTimeFormatterOptions,
pub(crate) value: FixedDecimal,
pub(crate) is_negative: bool,
}
impl Writeable for FormattedRelativeTime<'_> {
fn write_to_parts<S: writeable::PartsWrite + ?Sized>(&self, sink: &mut S) -> core::fmt::Result {
if self.options.numeric == Numeric::Auto {
let relatives = &self.formatter.rt.get().relatives;
if self.value.magnitude_range() == (0..=0) {
let i8_value = if self.is_negative {
-(self.value.digit_at(0) as i8)
} else {
self.value.digit_at(0) as i8
};
if let Some(v) = relatives.get(&i8_value) {
sink.with_part(parts::LITERAL, |s| s.write_str(v))?;
return Ok(());
}
}
}
if self.is_negative {
&self.formatter.rt.get().past
} else {
&self.formatter.rt.get().future
}
.get((&self.value).into(), &self.formatter.plural_rules)
.interpolate((self.formatter.fixed_decimal_format.format(&self.value),))
.write_to(sink)
}
}
writeable::impl_display_with_writeable!(FormattedRelativeTime<'_>);