From d845fb6507f32820644f24ebaa52af43be276689 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Mon, 16 Dec 2024 13:39:38 -0800 Subject: [PATCH] Add trim_end_if_integer to FixedDecimal (#5903) Fixes https://github.com/unicode-org/icu4x/issues/5902 --- ffi/capi/bindings/c/SignedFixedDecimal.h | 2 + .../cpp/icu4x/SignedFixedDecimal.d.hpp | 2 + .../bindings/cpp/icu4x/SignedFixedDecimal.hpp | 6 ++ .../bindings/dart/SignedFixedDecimal.g.dart | 10 ++++ ffi/capi/bindings/js/SignedFixedDecimal.d.ts | 2 + ffi/capi/bindings/js/SignedFixedDecimal.mjs | 7 +++ ffi/capi/src/fixed_decimal.rs | 10 ++++ utils/fixed_decimal/src/decimal.rs | 60 +++++++++++++++++++ 8 files changed, 99 insertions(+) diff --git a/ffi/capi/bindings/c/SignedFixedDecimal.h b/ffi/capi/bindings/c/SignedFixedDecimal.h index d703e1cc38e..21fb5c8a8f6 100644 --- a/ffi/capi/bindings/c/SignedFixedDecimal.h +++ b/ffi/capi/bindings/c/SignedFixedDecimal.h @@ -67,6 +67,8 @@ void icu4x_SignedFixedDecimal_trim_start_mv1(SignedFixedDecimal* self); void icu4x_SignedFixedDecimal_trim_end_mv1(SignedFixedDecimal* self); +void icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(SignedFixedDecimal* self); + void icu4x_SignedFixedDecimal_pad_start_mv1(SignedFixedDecimal* self, int16_t position); void icu4x_SignedFixedDecimal_pad_end_mv1(SignedFixedDecimal* self, int16_t position); diff --git a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp index 8b4adb670a0..22f17fd63f0 100644 --- a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.d.hpp @@ -73,6 +73,8 @@ class SignedFixedDecimal { inline void trim_end(); + inline void trim_end_if_integer(); + inline void pad_start(int16_t position); inline void pad_end(int16_t position); diff --git a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp index 524b5569bd5..e47ea847d62 100644 --- a/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp +++ b/ffi/capi/bindings/cpp/icu4x/SignedFixedDecimal.hpp @@ -69,6 +69,8 @@ namespace capi { void icu4x_SignedFixedDecimal_trim_end_mv1(icu4x::capi::SignedFixedDecimal* self); + void icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(icu4x::capi::SignedFixedDecimal* self); + void icu4x_SignedFixedDecimal_pad_start_mv1(icu4x::capi::SignedFixedDecimal* self, int16_t position); void icu4x_SignedFixedDecimal_pad_end_mv1(icu4x::capi::SignedFixedDecimal* self, int16_t position); @@ -207,6 +209,10 @@ inline void icu4x::SignedFixedDecimal::trim_end() { icu4x::capi::icu4x_SignedFixedDecimal_trim_end_mv1(this->AsFFI()); } +inline void icu4x::SignedFixedDecimal::trim_end_if_integer() { + icu4x::capi::icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(this->AsFFI()); +} + inline void icu4x::SignedFixedDecimal::pad_start(int16_t position) { icu4x::capi::icu4x_SignedFixedDecimal_pad_start_mv1(this->AsFFI(), position); diff --git a/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart b/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart index ef5017554b0..d1054ee04c4 100644 --- a/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart +++ b/ffi/capi/bindings/dart/SignedFixedDecimal.g.dart @@ -161,6 +161,11 @@ final class SignedFixedDecimal implements ffi.Finalizable { _icu4x_SignedFixedDecimal_trim_end_mv1(_ffi); } + /// See the [Rust documentation for `trim_end_if_integer`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.UnsignedFixedDecimal.html#method.trim_end_if_integer) for more information. + void trimEndIfInteger() { + _icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(_ffi); + } + /// Zero-pad the [`SignedFixedDecimal`] on the left to a particular position /// /// See the [Rust documentation for `pad_start`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html#method.pad_start) for more information. @@ -336,6 +341,11 @@ external void _icu4x_SignedFixedDecimal_trim_start_mv1(ffi.Pointer s // ignore: non_constant_identifier_names external void _icu4x_SignedFixedDecimal_trim_end_mv1(ffi.Pointer self); +@meta.RecordUse() +@ffi.Native)>(isLeaf: true, symbol: 'icu4x_SignedFixedDecimal_trim_end_if_integer_mv1') +// ignore: non_constant_identifier_names +external void _icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(ffi.Pointer self); + @meta.RecordUse() @ffi.Native, ffi.Int16)>(isLeaf: true, symbol: 'icu4x_SignedFixedDecimal_pad_start_mv1') // ignore: non_constant_identifier_names diff --git a/ffi/capi/bindings/js/SignedFixedDecimal.d.ts b/ffi/capi/bindings/js/SignedFixedDecimal.d.ts index 1b48a4e4bb1..c47f50f422d 100644 --- a/ffi/capi/bindings/js/SignedFixedDecimal.d.ts +++ b/ffi/capi/bindings/js/SignedFixedDecimal.d.ts @@ -51,6 +51,8 @@ export class SignedFixedDecimal { trimEnd(): void; + trimEndIfInteger(): void; + padStart(position: number): void; padEnd(position: number): void; diff --git a/ffi/capi/bindings/js/SignedFixedDecimal.mjs b/ffi/capi/bindings/js/SignedFixedDecimal.mjs index 0e5d069e6d9..40f4dc95d2b 100644 --- a/ffi/capi/bindings/js/SignedFixedDecimal.mjs +++ b/ffi/capi/bindings/js/SignedFixedDecimal.mjs @@ -245,6 +245,13 @@ export class SignedFixedDecimal { finally {} } + trimEndIfInteger() {wasm.icu4x_SignedFixedDecimal_trim_end_if_integer_mv1(this.ffiValue); + + try {} + + finally {} + } + padStart(position) {wasm.icu4x_SignedFixedDecimal_pad_start_mv1(this.ffiValue, position); try {} diff --git a/ffi/capi/src/fixed_decimal.rs b/ffi/capi/src/fixed_decimal.rs index 58b3d7bc409..33dcd2c0c1d 100644 --- a/ffi/capi/src/fixed_decimal.rs +++ b/ffi/capi/src/fixed_decimal.rs @@ -278,6 +278,16 @@ pub mod ffi { self.0.absolute.trim_end() } + #[diplomat::rust_link(fixed_decimal::UnsignedFixedDecimal::trim_end_if_integer, FnInStruct)] + #[diplomat::rust_link( + fixed_decimal::UnsignedFixedDecimal::trimmed_end_if_integer, + FnInStruct, + hidden + )] + pub fn trim_end_if_integer(&mut self) { + self.0.absolute.trim_end_if_integer() + } + /// Zero-pad the [`SignedFixedDecimal`] on the left to a particular position #[diplomat::rust_link(fixed_decimal::FixedDecimal::pad_start, FnInStruct)] #[diplomat::rust_link(fixed_decimal::FixedDecimal::padded_start, FnInStruct, hidden)] diff --git a/utils/fixed_decimal/src/decimal.rs b/utils/fixed_decimal/src/decimal.rs index cdb9877c431..baa28f028fc 100644 --- a/utils/fixed_decimal/src/decimal.rs +++ b/utils/fixed_decimal/src/decimal.rs @@ -680,6 +680,66 @@ impl UnsignedFixedDecimal { self.check_invariants(); } + /// Returns this number with its trailing zeros removed, + /// but only if the number is an integer + /// + /// # Examples + /// + /// ``` + /// use fixed_decimal::UnsignedFixedDecimal; + /// + /// let dec = UnsignedFixedDecimal::from(12340000u32) + /// .multiplied_pow10(-2); + /// assert_eq!("123400.00", dec.to_string()); + /// assert_eq!("123400", dec.trimmed_end_if_integer().to_string()); + /// + /// // No effect if there are nonzero fractional digits: + /// let dec = UnsignedFixedDecimal::from(123400u32) + /// .multiplied_pow10(-4) + /// .padded_start(4); + /// assert_eq!("0012.3400", dec.to_string()); + /// assert_eq!("0012.3400", dec.trimmed_end_if_integer().to_string()); + /// ``` + pub fn trimmed_end_if_integer(mut self) -> Self { + self.trim_end_if_integer(); + self + } + + /// Removes the trailing zeros of this number, + /// but only if the number is an integer + /// + /// # Examples + /// + /// ``` + /// use fixed_decimal::UnsignedFixedDecimal; + /// + /// let mut dec = UnsignedFixedDecimal::from(12340000u32) + /// .multiplied_pow10(-2); + /// assert_eq!("123400.00", dec.to_string()); + /// + /// dec.trim_end_if_integer(); + /// assert_eq!("123400", dec.to_string()); + /// + /// // No effect on trailing zeros in the integer: + /// dec.trim_end_if_integer(); + /// assert_eq!("123400", dec.to_string()); + /// + /// // No effect if there are nonzero fractional digits: + /// dec.multiply_pow10(-4); + /// dec.pad_start(4); + /// assert_eq!("0012.3400", dec.to_string()); + /// + /// dec.trim_end_if_integer(); + /// assert_eq!("0012.3400", dec.to_string()); + /// ``` + pub fn trim_end_if_integer(&mut self) { + if self.nonzero_magnitude_end() >= 0 { + self.lower_magnitude = 0; + } + #[cfg(debug_assertions)] + self.check_invariants(); + } + /// Returns this number padded with leading zeros on a particular position. /// /// Negative position numbers have no effect.