Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add impl From<&CompactDecimal> for PluralOperands #4828

Merged
merged 7 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- Added `total_cmp` functions to `Locale` and other types to make them easier to use in `BTreeSet` (https://github.com/unicode-org/icu4x/pull/4608)
- `icu_locid_transform`
- Add `LocaleExpander::minimize_favor_script` (https://github.com/unicode-org/icu4x/pull/4752)
- `icu_plurals`
- Added support for `CompactDecimal` (https://github.com/unicode-org/icu4x/pull/4828)
- `icu_properties`
- Add `Aran` script code (https://github.com/unicode-org/icu4x/pull/4426)
- Mark additional constructors as `const` (https://github.com/unicode-org/icu4x/pull/4584, https://github.com/unicode-org/icu4x/pull/4574)
Expand Down Expand Up @@ -48,6 +50,8 @@
- Deprecate `Hebrew::new_always_precomputing()`, `Date::try_new_hebrew_date_with_calendar()`, `DateTime::try_new_hebrew_datetime_with_calendar()`. The new implementation of the Hebrew calendar is faster and we do not need APIs for precomputation. (https://github.com/unicode-org/icu4x/pulls/4532)
- `databake`
- Add `impl Bake for PhantomData<T>` (https://github.com/unicode-org/icu4x/pull/4663)
- `fixed_decimal`
- Changed type of compact exponent from `i16` to `u8` (https://github.com/unicode-org/icu4x/pull/4828)
- `litemap`
- Add `impl IntoIterator for LiteMap` by splitting `StoreIterableMut` trait (https://github.com/unicode-org/icu4x/pull/4359)
- `yoke`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -629,14 +629,15 @@ impl CompactDecimalFormatter {
&'l self,
value: &'l CompactDecimal,
) -> Result<FormattedCompactDecimal<'l>, CompactDecimalError> {
let log10_type = value.significand().nonzero_magnitude_start() + value.exponent();
let log10_type =
value.significand().nonzero_magnitude_start() + i16::from(value.exponent());

let (plural_map, expected_exponent) =
self.plural_map_and_exponent_for_magnitude(log10_type);
if value.exponent() != i16::from(expected_exponent) {
if value.exponent() != expected_exponent {
return Err(CompactDecimalError::Exponent {
actual: value.exponent(),
expected: i16::from(expected_exponent),
expected: expected_exponent,
log10_type,
});
}
Expand Down
4 changes: 2 additions & 2 deletions components/experimental/src/compactdecimal/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ pub enum CompactDecimalError {
#[displaydoc("Expected compact exponent {expected} for 10^{log10_type}, got {actual}")]
Exponent {
/// The compact decimal exponent passed to the formatter.
actual: i16,
actual: u8,
/// The appropriate compact decimal exponent for a number of the given magnitude.
expected: i16,
expected: u8,
/// The magnitude of the number being formatted.
log10_type: i16,
},
Expand Down
79 changes: 69 additions & 10 deletions components/plurals/src/operands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::isize;
use core::num::ParseIntError;
use core::str::FromStr;
use displaydoc::Display;
use fixed_decimal::FixedDecimal;
use fixed_decimal::{CompactDecimal, FixedDecimal};

/// A full plural operands representation of a number. See [CLDR Plural Rules](http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules) for complete operands description.
/// Plural operands in compliance with [CLDR Plural Rules](http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules).
Expand Down Expand Up @@ -235,25 +235,25 @@ macro_rules! impl_signed_integer_type {
impl_integer_type!(u8 u16 u32 u64 u128 usize);
impl_signed_integer_type!(i8 i16 i32 i64 i128 isize);

impl From<&FixedDecimal> for PluralOperands {
/// Converts a [`fixed_decimal::FixedDecimal`] to [`PluralOperands`]. Retains at most 18
/// digits each from the integer and fraction parts.
fn from(dec: &FixedDecimal) -> Self {
impl PluralOperands {
fn from_significand_and_exponent(dec: &FixedDecimal, exp: u8) -> PluralOperands {
let exp_i16 = i16::from(exp);

let mag_range = dec.magnitude_range();
let mag_high = core::cmp::min(17, *mag_range.end());
let mag_low = core::cmp::max(-18, *mag_range.start());
let mag_high = core::cmp::min(17, *mag_range.end() + exp_i16);
let mag_low = core::cmp::max(-18, *mag_range.start() + exp_i16);

let mut i: u64 = 0;
for magnitude in (0..=mag_high).rev() {
i *= 10;
i += dec.digit_at(magnitude) as u64;
i += dec.digit_at(magnitude - exp_i16) as u64;
}

let mut f: u64 = 0;
let mut t: u64 = 0;
let mut w: usize = 0;
for magnitude in (mag_low..=-1).rev() {
let digit = dec.digit_at(magnitude) as u64;
let digit = dec.digit_at(magnitude - exp_i16) as u64;
f *= 10;
f += digit;
if digit != 0 {
Expand All @@ -268,7 +268,66 @@ impl From<&FixedDecimal> for PluralOperands {
w,
f,
t,
c: 0,
c: usize::from(exp),
}
}
}

impl From<&FixedDecimal> for PluralOperands {
/// Converts a [`fixed_decimal::FixedDecimal`] to [`PluralOperands`]. Retains at most 18
/// digits each from the integer and fraction parts.
fn from(dec: &FixedDecimal) -> Self {
Self::from_significand_and_exponent(dec, 0)
}
}

impl From<&CompactDecimal> for PluralOperands {
/// Converts a [`fixed_decimal::CompactDecimal`] to [`PluralOperands`]. Retains at most 18
/// digits each from the integer and fraction parts.
///
/// # Examples
///
/// ```
/// use fixed_decimal::CompactDecimal;
/// use fixed_decimal::FixedDecimal;
/// use icu::locid::locale;
/// use icu::plurals::rules::RawPluralOperands;
/// use icu::plurals::PluralCategory;
/// use icu::plurals::PluralOperands;
/// use icu::plurals::PluralRules;
///
/// let fixed_decimal = "1000000.20".parse::<FixedDecimal>().unwrap();
/// let compact_decimal = "1.00000020c6".parse::<CompactDecimal>().unwrap();
///
/// assert_eq!(
/// PluralOperands::from(RawPluralOperands {
/// i: 1000000,
/// v: 2,
/// w: 1,
/// f: 20,
/// t: 2,
/// c: 0,
/// }),
/// PluralOperands::from(&fixed_decimal)
/// );
///
/// assert_eq!(
/// PluralOperands::from(RawPluralOperands {
/// i: 1000000,
/// v: 2,
/// w: 1,
/// f: 20,
/// t: 2,
/// c: 6,
/// }),
/// PluralOperands::from(&compact_decimal)
/// );
///
/// let rules = PluralRules::try_new_cardinal(&locale!("fr").into()).unwrap();
/// assert_eq!(rules.category_for(&fixed_decimal), PluralCategory::Other);
/// assert_eq!(rules.category_for(&compact_decimal), PluralCategory::Many);
/// ```
fn from(compact: &CompactDecimal) -> Self {
Self::from_significand_and_exponent(compact.significand(), compact.exponent())
}
}
2 changes: 1 addition & 1 deletion tutorials/rust/baked/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl_data_provider!(BakedProvider);
fn main() {
let rules = PluralRules::try_new_cardinal_unstable(&BakedProvider, &locale!("ru").into())
.expect("locale 'ru' should be present in the baked data");
let result = rules.category_for(&3.into());
let result = rules.category_for(3);
assert_eq!(result, PluralCategory::Few);
println!("{:?}", result);
}
2 changes: 1 addition & 1 deletion tutorials/rust/custom_compiled/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use icu::plurals::PluralRules;
fn main() {
let rules = PluralRules::try_new_cardinal(&locale!("ru").into())
.expect("locale 'ru' should be present in the compiled data");
let result = rules.category_for(&3.into());
let result = rules.category_for(3);
assert_eq!(result, PluralCategory::Few);
println!("{result:?}");
}
2 changes: 1 addition & 1 deletion tutorials/rust/default/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use icu::plurals::PluralRules;
fn main() {
let rules = PluralRules::try_new_cardinal(&locale!("ru").into())
.expect("locale 'ru' should be present in the compiled data");
let result = rules.category_for(&3.into());
let result = rules.category_for(3);
assert_eq!(result, PluralCategory::Few);
println!("{result:?}");
}
6 changes: 3 additions & 3 deletions utils/fixed_decimal/src/compact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ use crate::FixedDecimal;
#[derive(Debug, Clone, PartialEq)]
pub struct CompactDecimal {
significand: FixedDecimal,
exponent: i16,
exponent: u8,
}

impl CompactDecimal {
/// Constructs a [`CompactDecimal`] from its significand and exponent.
pub fn from_significand_and_exponent(significand: FixedDecimal, exponent: u8) -> Self {
Self {
significand,
exponent: exponent.into(),
exponent,
}
}

Expand Down Expand Up @@ -74,7 +74,7 @@ impl CompactDecimal {
/// assert_eq!(CompactDecimal::from_str("+1.20c6").unwrap().exponent(), 6);
/// assert_eq!(CompactDecimal::from_str("1729").unwrap().exponent(), 0);
/// ```
pub fn exponent(&self) -> i16 {
pub fn exponent(&self) -> u8 {
self.exponent
}
}
Expand Down