use super::{
compact_options::{CompactCurrencyFormatterOptions, Width},
CurrencyCode,
};
use crate::{
compactdecimal::CompactDecimalFormatter,
dimension::provider::{
currency::{self, CurrencyEssentialsV1},
currency_compact::ShortCurrencyCompactV1,
},
};
use fixed_decimal::SignedFixedDecimal;
use writeable::Writeable;
pub struct FormattedCompactCurrency<'l> {
pub(crate) value: &'l SignedFixedDecimal,
pub(crate) currency_code: CurrencyCode,
pub(crate) options: &'l CompactCurrencyFormatterOptions,
pub(crate) essential: &'l CurrencyEssentialsV1<'l>,
pub(crate) _short_currency_compact: &'l ShortCurrencyCompactV1<'l>,
pub(crate) compact_decimal_formatter: &'l CompactDecimalFormatter,
}
writeable::impl_display_with_writeable!(FormattedCompactCurrency<'_>);
impl<'l> Writeable for FormattedCompactCurrency<'l> {
fn write_to<W>(&self, sink: &mut W) -> core::result::Result<(), core::fmt::Error>
where
W: core::fmt::Write + ?Sized,
{
let config = self
.essential
.pattern_config_map
.get_copied(&self.currency_code.0.to_unvalidated())
.unwrap_or(self.essential.default_pattern_config);
let placeholder_index = match self.options.width {
Width::Short => config.short_placeholder_value,
Width::Narrow => config.narrow_placeholder_value,
};
let currency_placeholder = match placeholder_index {
Some(currency::PlaceholderValue::Index(index)) => self
.essential
.placeholders
.get(index.into())
.ok_or(core::fmt::Error)?,
Some(currency::PlaceholderValue::ISO) | None => self.currency_code.0.as_str(),
};
let pattern_selection = match self.options.width {
Width::Short => config.short_pattern_selection,
Width::Narrow => config.narrow_pattern_selection,
};
let pattern = match pattern_selection {
currency::PatternSelection::Standard => self.essential.standard_pattern.as_ref(),
currency::PatternSelection::StandardAlphaNextToNumber => self
.essential
.standard_alpha_next_to_number_pattern
.as_ref(),
}
.ok_or(core::fmt::Error)?;
pattern
.interpolate((
self.compact_decimal_formatter
.format_fixed_decimal(self.value),
currency_placeholder,
))
.write_to(sink)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use icu_locale_core::locale;
use tinystr::*;
use writeable::assert_writeable_eq;
use crate::dimension::currency::{compact_formatter::CompactCurrencyFormatter, CurrencyCode};
#[test]
pub fn test_en_us() {
let locale = locale!("en-US").into();
let currency_code = CurrencyCode(tinystr!(3, "USD"));
let fmt = CompactCurrencyFormatter::try_new(locale, Default::default()).unwrap();
let positive_value = "12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&positive_value, currency_code);
assert_writeable_eq!(formatted_currency, "$12K");
let negative_value = "-12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&negative_value, currency_code);
assert_writeable_eq!(formatted_currency, "$-12K");
}
#[test]
pub fn test_fr_fr() {
let locale = locale!("fr-FR").into();
let currency_code = CurrencyCode(tinystr!(3, "EUR"));
let fmt = CompactCurrencyFormatter::try_new(locale, Default::default()).unwrap();
let positive_value = "12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&positive_value, currency_code);
assert_writeable_eq!(formatted_currency, "12\u{a0}k\u{a0}€");
let negative_value = "-12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&negative_value, currency_code);
assert_writeable_eq!(formatted_currency, "-12\u{a0}k\u{a0}€");
}
#[test]
pub fn test_zh_cn() {
let locale = locale!("zh-CN").into();
let currency_code = CurrencyCode(tinystr!(3, "CNY"));
let fmt = CompactCurrencyFormatter::try_new(locale, Default::default()).unwrap();
let positive_value = "12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&positive_value, currency_code);
assert_writeable_eq!(formatted_currency, "¥1.2万");
let negative_value = "-12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&negative_value, currency_code);
assert_writeable_eq!(formatted_currency, "¥-1.2万");
}
#[test]
pub fn test_ar_eg() {
let locale = locale!("ar-EG").into();
let currency_code = CurrencyCode(tinystr!(3, "EGP"));
let fmt = CompactCurrencyFormatter::try_new(locale, Default::default()).unwrap();
let positive_value = "12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&positive_value, currency_code);
assert_writeable_eq!(formatted_currency, "\u{200f}١٢\u{a0}ألف\u{a0}ج.م.\u{200f}"); let negative_value = "-12345.67".parse().unwrap();
let formatted_currency = fmt.format_fixed_decimal(&negative_value, currency_code);
assert_writeable_eq!(
formatted_currency,
"\u{200f}\u{61c}-١٢\u{a0}ألف\u{a0}ج.م.\u{200f}"
);
}
}