44
55use core:: fmt:: Display ;
66
7+ use crate :: input:: Decimal ;
8+ use crate :: Cow ;
79use crate :: {
8- error:: ExponentError ,
10+ error:: CompactExponentError ,
911 options:: CompactDecimalFormatterOptions ,
1012 preferences:: { CompactDecimalFormatterPreferences , DecimalFormatterPreferences } ,
1113 provider:: * ,
1214 DecimalFormatter ,
1315} ;
14- use alloc:: borrow:: Cow ;
15- use fixed_decimal:: { Decimal , UnsignedDecimal } ;
16+ #[ cfg( feature = "alloc" ) ]
17+ use alloc:: string:: String ;
18+ use fixed_decimal:: UnsignedDecimal ;
1619use icu_pattern:: { Pattern , PatternBackend , SinglePlaceholder } ;
1720use icu_plurals:: PluralRules ;
1821use icu_provider:: DataError ;
@@ -72,9 +75,7 @@ pub struct CompactDecimalFormatter {
7275}
7376
7477impl CompactDecimalFormatter {
75- /// Constructor that takes a selected locale and a list of preferences,
76- /// then collects all compiled data necessary to format numbers in short compact
77- /// decimal notation for the given locale.
78+ /// Creates a new short [`CompactDecimalFormatter`] from compiled data and an options bag.
7879 ///
7980 /// ✨ *Enabled with the `compiled_data` Cargo feature.*
8081 ///
@@ -85,11 +86,14 @@ impl CompactDecimalFormatter {
8586 /// ```
8687 /// use icu::decimal::CompactDecimalFormatter;
8788 /// use icu::locale::locale;
89+ /// use writeable::assert_writeable_eq;
8890 ///
89- /// CompactDecimalFormatter::try_new_short(
91+ /// let formatter = CompactDecimalFormatter::try_new_short(
9092 /// locale!("sv").into(),
9193 /// Default::default(),
92- /// );
94+ /// ).unwrap();
95+ ///
96+ /// assert_writeable_eq!(formatter.format(&1234.into()), "1,2 tn");
9397 /// ```
9498 #[ cfg( feature = "compiled_data" ) ]
9599 pub fn try_new_short (
@@ -98,10 +102,7 @@ impl CompactDecimalFormatter {
98102 ) -> Result < Self , DataError > {
99103 let locale = DecimalCompactShortV1 :: make_locale ( prefs. locale_preferences ) ;
100104 Ok ( Self {
101- decimal_formatter : DecimalFormatter :: try_new (
102- ( & prefs) . into ( ) ,
103- options. decimal_formatter_options ,
104- ) ?,
105+ decimal_formatter : DecimalFormatter :: try_new ( ( & prefs) . into ( ) , options. into ( ) ) ?,
105106 plural_rules : PluralRules :: try_new_cardinal ( ( & prefs) . into ( ) ) ?,
106107 compact_data : load_with_fallback :: < DecimalCompactShortV1 > (
107108 & Baked ,
@@ -143,7 +144,7 @@ impl CompactDecimalFormatter {
143144 decimal_formatter : DecimalFormatter :: try_new_unstable (
144145 provider,
145146 ( & prefs) . into ( ) ,
146- options. decimal_formatter_options ,
147+ options. into ( ) ,
147148 ) ?,
148149 plural_rules : PluralRules :: try_new_cardinal_unstable ( provider, ( & prefs) . into ( ) ) ?,
149150 compact_data : load_with_fallback :: < DecimalCompactShortV1 > (
@@ -158,9 +159,7 @@ impl CompactDecimalFormatter {
158159 } )
159160 }
160161
161- /// Constructor that takes a selected locale and a list of preferences,
162- /// then collects all compiled data necessary to format numbers in short compact
163- /// decimal notation for the given locale.
162+ /// Creates a new long [`CompactDecimalFormatter`] from compiled data and an options bag.
164163 ///
165164 /// ✨ *Enabled with the `compiled_data` Cargo feature.*
166165 ///
@@ -171,11 +170,14 @@ impl CompactDecimalFormatter {
171170 /// ```
172171 /// use icu::decimal::CompactDecimalFormatter;
173172 /// use icu::locale::locale;
173+ /// use writeable::assert_writeable_eq;
174174 ///
175- /// CompactDecimalFormatter::try_new_long(
175+ /// let formatter = CompactDecimalFormatter::try_new_long(
176176 /// locale!("sv").into(),
177177 /// Default::default(),
178- /// );
178+ /// ).unwrap();
179+ ///
180+ /// assert_writeable_eq!(formatter.format(&1234.into()), "1,2 tusen");
179181 /// ```
180182 #[ cfg( feature = "compiled_data" ) ]
181183 pub fn try_new_long (
@@ -184,10 +186,7 @@ impl CompactDecimalFormatter {
184186 ) -> Result < Self , DataError > {
185187 let locale = DecimalCompactLongV1 :: make_locale ( prefs. locale_preferences ) ;
186188 Ok ( Self {
187- decimal_formatter : DecimalFormatter :: try_new (
188- ( & prefs) . into ( ) ,
189- options. decimal_formatter_options ,
190- ) ?,
189+ decimal_formatter : DecimalFormatter :: try_new ( ( & prefs) . into ( ) , options. into ( ) ) ?,
191190 plural_rules : PluralRules :: try_new_cardinal ( ( & prefs) . into ( ) ) ?,
192191 compact_data : load_with_fallback :: < DecimalCompactLongV1 > (
193192 & Baked ,
@@ -229,7 +228,7 @@ impl CompactDecimalFormatter {
229228 decimal_formatter : DecimalFormatter :: try_new_unstable (
230229 provider,
231230 ( & prefs) . into ( ) ,
232- options. decimal_formatter_options ,
231+ options. into ( ) ,
233232 ) ?,
234233 plural_rules : PluralRules :: try_new_cardinal_unstable ( provider, ( & prefs) . into ( ) ) ?,
235234 compact_data : load_with_fallback :: < DecimalCompactLongV1 > (
@@ -249,14 +248,11 @@ impl CompactDecimalFormatter {
249248 /// The result may have a fractional digit only if it is compact and its
250249 /// significand is less than 10. Trailing fractional 0s are omitted.
251250 ///
252- /// Because the Decimal is mutated before formatting, this function
253- /// takes ownership of it.
254- ///
255251 /// # Examples
256252 ///
257253 /// ```
258254 /// use icu::decimal::CompactDecimalFormatter;
259- /// use icu::decimal::input::{Decimal, FloatPrecision, SignDisplay};
255+ /// use icu::decimal::input::{Decimal, SignDisplay};
260256 /// use icu::locale::locale;
261257 /// use writeable::assert_writeable_eq;
262258 ///
@@ -303,14 +299,6 @@ impl CompactDecimalFormatter {
303299 /// ),
304300 /// "+2.5K"
305301 /// );
306- ///
307- /// // Floating point inputs should use FloatPrecision::RoundTrip
308- /// assert_writeable_eq!(
309- /// short_english.format(
310- /// &Decimal::try_from_f64(999_499.99, FloatPrecision::RoundTrip).unwrap()
311- /// ),
312- /// "999K"
313- /// );
314302 /// ```
315303 ///
316304 /// The result is the nearest such compact number, with halfway cases-
@@ -354,6 +342,26 @@ impl CompactDecimalFormatter {
354342 /// "0.22"
355343 /// );
356344 /// ```
345+ ///
346+ /// Floating point inputs should use [`FloatPrecision::RoundTrip`](fixed_decimal::FloatPrecision::RoundTrip).
347+ ///
348+ /// ```
349+ /// # use icu::decimal::input::{Decimal, FloatPrecision};
350+ /// # use icu::decimal::CompactDecimalFormatter;
351+ /// # use icu::locale::locale;
352+ /// # use writeable::assert_writeable_eq;
353+ /// #
354+ /// # let short_english = CompactDecimalFormatter::try_new_short(
355+ /// # locale!("en").into(),
356+ /// # Default::default(),
357+ /// # ).unwrap();
358+ /// assert_writeable_eq!(
359+ /// short_english.format(
360+ /// &Decimal::try_from_f64(999_499.99, FloatPrecision::RoundTrip).unwrap()
361+ /// ),
362+ /// "999K"
363+ /// );
364+ /// ```
357365 pub fn format ( & self , value : & Decimal ) -> impl Writeable + Display + ' _ {
358366 let ( compact_pattern, significand) = self
359367 . compact_data
@@ -370,6 +378,15 @@ impl CompactDecimalFormatter {
370378 )
371379 }
372380
381+ /// Formats a [`Decimal`], returning a [`String`].
382+ ///
383+ /// ✨ *Enabled with the `alloc` Cargo feature.*
384+ #[ cfg( feature = "alloc" ) ]
385+ pub fn format_to_string ( & self , value : & Decimal ) -> String {
386+ use writeable:: Writeable ;
387+ self . format ( value) . write_to_string ( ) . into_owned ( )
388+ }
389+
373390 /// Formats a [`Decimal`] with a given exponent according to locale data.
374391 ///
375392 /// This is an advanced API; prefer using [`Self::format()`] in simple
@@ -395,7 +412,7 @@ impl CompactDecimalFormatter {
395412 /// # use icu::locale::locale;
396413 /// # use writeable::assert_writeable_eq;
397414 /// # use std::str::FromStr;
398- ///
415+ /// #
399416 /// # let short_french = CompactDecimalFormatter::try_new_short(
400417 /// # locale!("fr").into(),
401418 /// # Default::default(),
@@ -470,7 +487,7 @@ impl CompactDecimalFormatter {
470487 & ' l self ,
471488 significand : & ' l Decimal ,
472489 exponent : u8 ,
473- ) -> Result < impl Writeable + Display + ' l , ExponentError > {
490+ ) -> Result < impl Writeable + Display + ' l , CompactExponentError > {
474491 let log10_type = significand. absolute . nonzero_magnitude_start ( ) + i16:: from ( exponent) ;
475492
476493 let ( pattern, expected_exponent) = self
@@ -491,10 +508,10 @@ impl CompactDecimalFormatter {
491508 . unwrap_or ( ( Pattern :: < SinglePlaceholder > :: PASS_THROUGH , 0 ) ) ;
492509
493510 if exponent != expected_exponent {
494- return Err ( ExponentError {
511+ return Err ( CompactExponentError {
495512 actual : exponent,
496513 expected : expected_exponent,
497- log10_type,
514+ magnitude : log10_type,
498515 } ) ;
499516 }
500517
0 commit comments