From ca82fd852d2e64894f54b3a90982637e65d590a6 Mon Sep 17 00:00:00 2001 From: Younies Mahmoud Date: Wed, 18 Mar 2026 16:24:01 +0100 Subject: [PATCH] Add currency display options to CurrencyFormatter (#7785) Enhance the CurrencyFormatterOptions struct to include a currency_display field, allowing for different display styles (Symbol, NarrowSymbol, Code, Name). Implement tests for each display style in the format module, ensuring correct formatting for USD in the en-US locale. ## Changelog - Added currency display options to CurrencyFormatter - Implemented tests for various currency display styles --- .../src/dimension/currency/format.rs | 84 ++++++++++++++++++- .../src/dimension/currency/options.rs | 36 +++++++- 2 files changed, 117 insertions(+), 3 deletions(-) diff --git a/components/experimental/src/dimension/currency/format.rs b/components/experimental/src/dimension/currency/format.rs index 8f9158bdc94..45b4f5fff5d 100644 --- a/components/experimental/src/dimension/currency/format.rs +++ b/components/experimental/src/dimension/currency/format.rs @@ -5,12 +5,14 @@ // TODO: add more tests for this module to cover more locales & currencies. #[cfg(test)] mod tests { + use crate::dimension::currency::{ + formatter::CurrencyFormatter, options::CurrencyDisplay, options::CurrencyFormatterOptions, + CurrencyCode, + }; use icu_locale_core::locale; use tinystr::*; use writeable::assert_writeable_eq; - use crate::dimension::currency::{formatter::CurrencyFormatter, CurrencyCode}; - #[test] pub fn test_en_us() { let locale = locale!("en-US").into(); @@ -66,4 +68,82 @@ mod tests { "\u{61c}-\u{200f}١٢٬٣٤٥٫٦٧\u{a0}ج.م.\u{200f}" ); } + + #[test] + #[should_panic] // TODO(#7785): implement currencyDisplay + pub fn test_currency_display_code_en_us() { + let locale = locale!("en-US").into(); + let currency_code = CurrencyCode(tinystr!(3, "USD")); + let fmt = CurrencyFormatter::try_new( + locale, + CurrencyFormatterOptions { + currency_display: CurrencyDisplay::Code, + ..Default::default() + }, + ) + .unwrap(); + + let value = "12345.67".parse().unwrap(); + let formatted_currency = fmt.format_fixed_decimal(&value, ¤cy_code); + + assert_writeable_eq!(formatted_currency, "USD 12,345.67"); + } + + #[test] + pub fn test_currency_display_symbol_en_us() { + let locale = locale!("en-US").into(); + let currency_code = CurrencyCode(tinystr!(3, "USD")); + let fmt = CurrencyFormatter::try_new( + locale, + CurrencyFormatterOptions { + currency_display: CurrencyDisplay::Symbol, + ..Default::default() + }, + ) + .unwrap(); + + let value = "12345.67".parse().unwrap(); + let formatted_currency = fmt.format_fixed_decimal(&value, ¤cy_code); + + assert_writeable_eq!(formatted_currency, "$12,345.67"); + } + + #[test] + pub fn test_currency_display_narrow_symbol_en_us() { + let locale = locale!("en-US").into(); + let currency_code = CurrencyCode(tinystr!(3, "USD")); + let fmt = CurrencyFormatter::try_new( + locale, + CurrencyFormatterOptions { + currency_display: CurrencyDisplay::NarrowSymbol, + ..Default::default() + }, + ) + .unwrap(); + + let value = "12345.67".parse().unwrap(); + let formatted_currency = fmt.format_fixed_decimal(&value, ¤cy_code); + + assert_writeable_eq!(formatted_currency, "$12,345.67"); + } + + #[test] + #[should_panic] // TODO(#7785): implement currencyDisplay + pub fn test_currency_display_name_en_us() { + let locale = locale!("en-US").into(); + let currency_code = CurrencyCode(tinystr!(3, "USD")); + let fmt = CurrencyFormatter::try_new( + locale, + CurrencyFormatterOptions { + currency_display: CurrencyDisplay::Name, + ..Default::default() + }, + ) + .unwrap(); + + let value = "12345.67".parse().unwrap(); + let formatted_currency = fmt.format_fixed_decimal(&value, ¤cy_code); + + assert_writeable_eq!(formatted_currency, "12,345.67 US dollars"); + } } diff --git a/components/experimental/src/dimension/currency/options.rs b/components/experimental/src/dimension/currency/options.rs index a223054fe77..093e2051b51 100644 --- a/components/experimental/src/dimension/currency/options.rs +++ b/components/experimental/src/dimension/currency/options.rs @@ -15,14 +15,48 @@ use serde::{Deserialize, Serialize}; pub struct CurrencyFormatterOptions { /// The width of the currency format. pub width: Width, + + /// The display style for currencies. + /// Default is [`CurrencyDisplay::Symbol`]. + pub currency_display: CurrencyDisplay, } impl From for CurrencyFormatterOptions { fn from(width: Width) -> Self { - Self { width } + Self { + width, + currency_display: CurrencyDisplay::default(), + } + } +} + +impl From for CurrencyFormatterOptions { + fn from(currency_display: CurrencyDisplay) -> Self { + Self { + width: Width::default(), + currency_display, + } } } +#[derive(Default, Debug, Eq, PartialEq, Clone, Copy, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[non_exhaustive] +pub enum CurrencyDisplay { + /// Display with the default currency symbol. + #[default] + Symbol, + + /// Display with the narrow currency symbol. + NarrowSymbol, + + /// Display with the ISO currency code. + Code, + + /// Display with the localized currency name. + Name, +} + #[derive(Default, Debug, Eq, PartialEq, Clone, Copy, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[non_exhaustive]