Bug 1904750 Prefer DefaultDuration over previous inter-timestamp interval r=media...
[gecko.git] / intl / icu_capi / src / fixed_decimal.rs
blob9bb8fe19888cc42d24a7fc75a8ea30d08c776e30
1 // This file is part of ICU4X. For terms of use, please see the file
2 // called LICENSE at the top level of the ICU4X source tree
3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
5 use fixed_decimal::RoundingIncrement;
6 use fixed_decimal::Sign;
7 use fixed_decimal::SignDisplay;
9 #[diplomat::bridge]
10 pub mod ffi {
11     use alloc::boxed::Box;
12     use fixed_decimal::{DoublePrecision, FixedDecimal};
13     use writeable::Writeable;
15     use crate::errors::ffi::ICU4XError;
17     #[diplomat::opaque]
18     #[diplomat::rust_link(fixed_decimal::FixedDecimal, Struct)]
19     pub struct ICU4XFixedDecimal(pub FixedDecimal);
21     /// The sign of a FixedDecimal, as shown in formatting.
22     #[diplomat::rust_link(fixed_decimal::Sign, Enum)]
23     pub enum ICU4XFixedDecimalSign {
24         /// No sign (implicitly positive, e.g., 1729).
25         None,
26         /// A negative sign, e.g., -1729.
27         Negative,
28         /// An explicit positive sign, e.g., +1729.
29         Positive,
30     }
32     /// ECMA-402 compatible sign display preference.
33     #[diplomat::rust_link(fixed_decimal::SignDisplay, Enum)]
34     pub enum ICU4XFixedDecimalSignDisplay {
35         Auto,
36         Never,
37         Always,
38         ExceptZero,
39         Negative,
40     }
42     // TODO: Rename to `ICU4XFixedDecimalRoundingIncrement` for 2.0
43     /// Increment used in a rounding operation.
44     #[diplomat::rust_link(fixed_decimal::RoundingIncrement, Enum)]
45     pub enum ICU4XRoundingIncrement {
46         MultiplesOf1,
47         MultiplesOf2,
48         MultiplesOf5,
49         MultiplesOf25,
50     }
52     impl ICU4XFixedDecimal {
53         /// Construct an [`ICU4XFixedDecimal`] from an integer.
54         #[diplomat::rust_link(fixed_decimal::FixedDecimal, Struct)]
55         #[diplomat::attr(dart, disable)]
56         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_i32")]
57         pub fn create_from_i32(v: i32) -> Box<ICU4XFixedDecimal> {
58             Box::new(ICU4XFixedDecimal(FixedDecimal::from(v)))
59         }
61         /// Construct an [`ICU4XFixedDecimal`] from an integer.
62         #[diplomat::rust_link(fixed_decimal::FixedDecimal, Struct)]
63         #[diplomat::attr(dart, disable)]
64         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_u32")]
65         pub fn create_from_u32(v: u32) -> Box<ICU4XFixedDecimal> {
66             Box::new(ICU4XFixedDecimal(FixedDecimal::from(v)))
67         }
69         /// Construct an [`ICU4XFixedDecimal`] from an integer.
70         #[diplomat::rust_link(fixed_decimal::FixedDecimal, Struct)]
71         #[diplomat::attr(dart, rename = "from_int")]
72         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_i64")]
73         pub fn create_from_i64(v: i64) -> Box<ICU4XFixedDecimal> {
74             Box::new(ICU4XFixedDecimal(FixedDecimal::from(v)))
75         }
77         /// Construct an [`ICU4XFixedDecimal`] from an integer.
78         #[diplomat::rust_link(fixed_decimal::FixedDecimal, Struct)]
79         #[diplomat::attr(dart, disable)]
80         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_u64")]
81         pub fn create_from_u64(v: u64) -> Box<ICU4XFixedDecimal> {
82             Box::new(ICU4XFixedDecimal(FixedDecimal::from(v)))
83         }
85         /// Construct an [`ICU4XFixedDecimal`] from an integer-valued float
86         #[diplomat::rust_link(fixed_decimal::FixedDecimal::try_from_f64, FnInStruct)]
87         #[diplomat::rust_link(fixed_decimal::FloatPrecision, Enum)]
88         #[diplomat::rust_link(fixed_decimal::DoublePrecision, Enum, hidden)]
89         #[diplomat::attr(dart, disable)]
90         #[diplomat::attr(dart, rename = "from_double_with_integer_precision")]
91         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_f64_with_integer_precision")]
92         pub fn create_from_f64_with_integer_precision(
93             f: f64,
94         ) -> Result<Box<ICU4XFixedDecimal>, ICU4XError> {
95             let precision = DoublePrecision::Integer;
96             Ok(Box::new(ICU4XFixedDecimal(FixedDecimal::try_from_f64(
97                 f, precision,
98             )?)))
99         }
101         /// Construct an [`ICU4XFixedDecimal`] from an float, with a given power of 10 for the lower magnitude
102         #[diplomat::rust_link(fixed_decimal::FixedDecimal::try_from_f64, FnInStruct)]
103         #[diplomat::rust_link(fixed_decimal::FloatPrecision, Enum)]
104         #[diplomat::rust_link(fixed_decimal::DoublePrecision, Enum, hidden)]
105         #[diplomat::attr(dart, rename = "from_double_with_lower_magnitude")]
106         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_f64_with_lower_magnitude")]
107         pub fn create_from_f64_with_lower_magnitude(
108             f: f64,
109             magnitude: i16,
110         ) -> Result<Box<ICU4XFixedDecimal>, ICU4XError> {
111             let precision = DoublePrecision::Magnitude(magnitude);
112             Ok(Box::new(ICU4XFixedDecimal(FixedDecimal::try_from_f64(
113                 f, precision,
114             )?)))
115         }
117         /// Construct an [`ICU4XFixedDecimal`] from an float, for a given number of significant digits
118         #[diplomat::rust_link(fixed_decimal::FixedDecimal::try_from_f64, FnInStruct)]
119         #[diplomat::rust_link(fixed_decimal::FloatPrecision, Enum)]
120         #[diplomat::rust_link(fixed_decimal::DoublePrecision, Enum, hidden)]
121         #[diplomat::attr(dart, rename = "from_double_with_significant_digits")]
122         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_f64_with_significant_digits")]
123         pub fn create_from_f64_with_significant_digits(
124             f: f64,
125             digits: u8,
126         ) -> Result<Box<ICU4XFixedDecimal>, ICU4XError> {
127             let precision = DoublePrecision::SignificantDigits(digits);
128             Ok(Box::new(ICU4XFixedDecimal(FixedDecimal::try_from_f64(
129                 f, precision,
130             )?)))
131         }
133         /// Construct an [`ICU4XFixedDecimal`] from an float, with enough digits to recover
134         /// the original floating point in IEEE 754 without needing trailing zeros
135         #[diplomat::rust_link(fixed_decimal::FixedDecimal::try_from_f64, FnInStruct)]
136         #[diplomat::rust_link(fixed_decimal::FloatPrecision, Enum)]
137         #[diplomat::rust_link(fixed_decimal::DoublePrecision, Enum, hidden)]
138         #[diplomat::attr(dart, rename = "from_double_with_double_precision")]
139         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_f64_with_floating_precision")]
140         pub fn create_from_f64_with_floating_precision(
141             f: f64,
142         ) -> Result<Box<ICU4XFixedDecimal>, ICU4XError> {
143             let precision = DoublePrecision::Floating;
144             Ok(Box::new(ICU4XFixedDecimal(FixedDecimal::try_from_f64(
145                 f, precision,
146             )?)))
147         }
149         /// Construct an [`ICU4XFixedDecimal`] from a string.
150         #[diplomat::rust_link(fixed_decimal::FixedDecimal::from_str, FnInStruct)]
151         #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_string")]
152         pub fn create_from_string(v: &DiplomatStr) -> Result<Box<ICU4XFixedDecimal>, ICU4XError> {
153             Ok(Box::new(ICU4XFixedDecimal(FixedDecimal::try_from(v)?)))
154         }
156         #[diplomat::rust_link(fixed_decimal::FixedDecimal::digit_at, FnInStruct)]
157         pub fn digit_at(&self, magnitude: i16) -> u8 {
158             self.0.digit_at(magnitude)
159         }
161         #[diplomat::rust_link(fixed_decimal::FixedDecimal::magnitude_range, FnInStruct)]
162         #[diplomat::attr(supports = accessors, getter)]
163         pub fn magnitude_start(&self) -> i16 {
164             *self.0.magnitude_range().start()
165         }
167         #[diplomat::rust_link(fixed_decimal::FixedDecimal::magnitude_range, FnInStruct)]
168         #[diplomat::attr(supports = accessors, getter)]
169         pub fn magnitude_end(&self) -> i16 {
170             *self.0.magnitude_range().end()
171         }
173         #[diplomat::rust_link(fixed_decimal::FixedDecimal::nonzero_magnitude_start, FnInStruct)]
174         #[diplomat::attr(supports = accessors, getter)]
175         pub fn nonzero_magnitude_start(&self) -> i16 {
176             self.0.nonzero_magnitude_start()
177         }
179         #[diplomat::rust_link(fixed_decimal::FixedDecimal::nonzero_magnitude_end, FnInStruct)]
180         #[diplomat::attr(supports = accessors, getter)]
181         pub fn nonzero_magnitude_end(&self) -> i16 {
182             self.0.nonzero_magnitude_end()
183         }
185         #[diplomat::rust_link(fixed_decimal::FixedDecimal::is_zero, FnInStruct)]
186         #[diplomat::attr(supports = accessors, getter)]
187         pub fn is_zero(&self) -> bool {
188             self.0.is_zero()
189         }
191         /// Multiply the [`ICU4XFixedDecimal`] by a given power of ten.
192         #[diplomat::rust_link(fixed_decimal::FixedDecimal::multiply_pow10, FnInStruct)]
193         #[diplomat::rust_link(fixed_decimal::FixedDecimal::multiplied_pow10, FnInStruct, hidden)]
194         pub fn multiply_pow10(&mut self, power: i16) {
195             self.0.multiply_pow10(power)
196         }
198         #[diplomat::rust_link(fixed_decimal::FixedDecimal::sign, FnInStruct)]
199         #[diplomat::attr(supports = accessors, getter)]
200         pub fn sign(&self) -> ICU4XFixedDecimalSign {
201             self.0.sign().into()
202         }
204         /// Set the sign of the [`ICU4XFixedDecimal`].
205         #[diplomat::rust_link(fixed_decimal::FixedDecimal::set_sign, FnInStruct)]
206         #[diplomat::rust_link(fixed_decimal::FixedDecimal::with_sign, FnInStruct, hidden)]
207         #[diplomat::attr(supports = accessors, setter = "sign")]
208         pub fn set_sign(&mut self, sign: ICU4XFixedDecimalSign) {
209             self.0.set_sign(sign.into())
210         }
212         #[diplomat::rust_link(fixed_decimal::FixedDecimal::apply_sign_display, FnInStruct)]
213         #[diplomat::rust_link(fixed_decimal::FixedDecimal::with_sign_display, FnInStruct, hidden)]
214         pub fn apply_sign_display(&mut self, sign_display: ICU4XFixedDecimalSignDisplay) {
215             self.0.apply_sign_display(sign_display.into())
216         }
218         #[diplomat::rust_link(fixed_decimal::FixedDecimal::trim_start, FnInStruct)]
219         #[diplomat::rust_link(fixed_decimal::FixedDecimal::trimmed_start, FnInStruct, hidden)]
220         pub fn trim_start(&mut self) {
221             self.0.trim_start()
222         }
224         #[diplomat::rust_link(fixed_decimal::FixedDecimal::trim_end, FnInStruct)]
225         #[diplomat::rust_link(fixed_decimal::FixedDecimal::trimmed_end, FnInStruct, hidden)]
226         pub fn trim_end(&mut self) {
227             self.0.trim_end()
228         }
230         /// Zero-pad the [`ICU4XFixedDecimal`] on the left to a particular position
231         #[diplomat::rust_link(fixed_decimal::FixedDecimal::pad_start, FnInStruct)]
232         #[diplomat::rust_link(fixed_decimal::FixedDecimal::padded_start, FnInStruct, hidden)]
233         pub fn pad_start(&mut self, position: i16) {
234             self.0.pad_start(position)
235         }
237         /// Zero-pad the [`ICU4XFixedDecimal`] on the right to a particular position
238         #[diplomat::rust_link(fixed_decimal::FixedDecimal::pad_end, FnInStruct)]
239         #[diplomat::rust_link(fixed_decimal::FixedDecimal::padded_end, FnInStruct, hidden)]
240         pub fn pad_end(&mut self, position: i16) {
241             self.0.pad_end(position)
242         }
244         /// Truncate the [`ICU4XFixedDecimal`] on the left to a particular position, deleting digits if necessary. This is useful for, e.g. abbreviating years
245         /// ("2022" -> "22")
246         #[diplomat::rust_link(fixed_decimal::FixedDecimal::set_max_position, FnInStruct)]
247         #[diplomat::rust_link(fixed_decimal::FixedDecimal::with_max_position, FnInStruct, hidden)]
248         pub fn set_max_position(&mut self, position: i16) {
249             self.0.set_max_position(position)
250         }
252         #[diplomat::rust_link(fixed_decimal::FixedDecimal::trunc, FnInStruct)]
253         #[diplomat::rust_link(fixed_decimal::FixedDecimal::trunced, FnInStruct, hidden)]
254         pub fn trunc(&mut self, position: i16) {
255             self.0.trunc(position)
256         }
258         #[diplomat::rust_link(fixed_decimal::FixedDecimal::trunc_to_increment, FnInStruct)]
259         #[diplomat::rust_link(
260             fixed_decimal::FixedDecimal::trunced_to_increment,
261             FnInStruct,
262             hidden
263         )]
264         pub fn trunc_to_increment(&mut self, position: i16, increment: ICU4XRoundingIncrement) {
265             self.0.trunc_to_increment(position, increment.into())
266         }
268         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_trunc, FnInStruct)]
269         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_trunced, FnInStruct, hidden)]
270         pub fn half_trunc(&mut self, position: i16) {
271             self.0.half_trunc(position)
272         }
274         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_trunc_to_increment, FnInStruct)]
275         #[diplomat::rust_link(
276             fixed_decimal::FixedDecimal::half_trunced_to_increment,
277             FnInStruct,
278             hidden
279         )]
280         pub fn half_trunc_to_increment(
281             &mut self,
282             position: i16,
283             increment: ICU4XRoundingIncrement,
284         ) {
285             self.0.half_trunc_to_increment(position, increment.into())
286         }
288         #[diplomat::rust_link(fixed_decimal::FixedDecimal::expand, FnInStruct)]
289         #[diplomat::rust_link(fixed_decimal::FixedDecimal::expanded, FnInStruct, hidden)]
290         pub fn expand(&mut self, position: i16) {
291             self.0.expand(position)
292         }
294         #[diplomat::rust_link(fixed_decimal::FixedDecimal::expand_to_increment, FnInStruct)]
295         #[diplomat::rust_link(
296             fixed_decimal::FixedDecimal::expanded_to_increment,
297             FnInStruct,
298             hidden
299         )]
300         pub fn expand_to_increment(&mut self, position: i16, increment: ICU4XRoundingIncrement) {
301             self.0.expand_to_increment(position, increment.into())
302         }
304         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_expand, FnInStruct)]
305         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_expanded, FnInStruct, hidden)]
306         pub fn half_expand(&mut self, position: i16) {
307             self.0.half_expand(position)
308         }
310         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_expand_to_increment, FnInStruct)]
311         #[diplomat::rust_link(
312             fixed_decimal::FixedDecimal::half_expanded_to_increment,
313             FnInStruct,
314             hidden
315         )]
316         pub fn half_expand_to_increment(
317             &mut self,
318             position: i16,
319             increment: ICU4XRoundingIncrement,
320         ) {
321             self.0.half_expand_to_increment(position, increment.into())
322         }
324         #[diplomat::rust_link(fixed_decimal::FixedDecimal::ceil, FnInStruct)]
325         #[diplomat::rust_link(fixed_decimal::FixedDecimal::ceiled, FnInStruct, hidden)]
326         pub fn ceil(&mut self, position: i16) {
327             self.0.ceil(position)
328         }
330         #[diplomat::rust_link(fixed_decimal::FixedDecimal::ceil_to_increment, FnInStruct)]
331         #[diplomat::rust_link(fixed_decimal::FixedDecimal::ceiled_to_increment, FnInStruct, hidden)]
332         pub fn ceil_to_increment(&mut self, position: i16, increment: ICU4XRoundingIncrement) {
333             self.0.ceil_to_increment(position, increment.into())
334         }
336         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_ceil, FnInStruct)]
337         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_ceiled, FnInStruct, hidden)]
338         pub fn half_ceil(&mut self, position: i16) {
339             self.0.half_ceil(position)
340         }
342         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_ceil_to_increment, FnInStruct)]
343         #[diplomat::rust_link(
344             fixed_decimal::FixedDecimal::half_ceiled_to_increment,
345             FnInStruct,
346             hidden
347         )]
348         pub fn half_ceil_to_increment(&mut self, position: i16, increment: ICU4XRoundingIncrement) {
349             self.0.half_ceil_to_increment(position, increment.into())
350         }
352         #[diplomat::rust_link(fixed_decimal::FixedDecimal::floor, FnInStruct)]
353         #[diplomat::rust_link(fixed_decimal::FixedDecimal::floored, FnInStruct, hidden)]
354         pub fn floor(&mut self, position: i16) {
355             self.0.floor(position)
356         }
358         #[diplomat::rust_link(fixed_decimal::FixedDecimal::floor_to_increment, FnInStruct)]
359         #[diplomat::rust_link(
360             fixed_decimal::FixedDecimal::floored_to_increment,
361             FnInStruct,
362             hidden
363         )]
364         pub fn floor_to_increment(&mut self, position: i16, increment: ICU4XRoundingIncrement) {
365             self.0.floor_to_increment(position, increment.into())
366         }
368         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_floor, FnInStruct)]
369         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_floored, FnInStruct, hidden)]
370         pub fn half_floor(&mut self, position: i16) {
371             self.0.half_floor(position)
372         }
374         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_floor_to_increment, FnInStruct)]
375         #[diplomat::rust_link(
376             fixed_decimal::FixedDecimal::half_floored_to_increment,
377             FnInStruct,
378             hidden
379         )]
380         pub fn half_floor_to_increment(
381             &mut self,
382             position: i16,
383             increment: ICU4XRoundingIncrement,
384         ) {
385             self.0.half_floor_to_increment(position, increment.into())
386         }
388         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_even, FnInStruct)]
389         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_evened, FnInStruct, hidden)]
390         pub fn half_even(&mut self, position: i16) {
391             self.0.half_even(position)
392         }
394         #[diplomat::rust_link(fixed_decimal::FixedDecimal::half_even_to_increment, FnInStruct)]
395         #[diplomat::rust_link(
396             fixed_decimal::FixedDecimal::half_evened_to_increment,
397             FnInStruct,
398             hidden
399         )]
400         pub fn half_even_to_increment(&mut self, position: i16, increment: ICU4XRoundingIncrement) {
401             self.0.half_even_to_increment(position, increment.into())
402         }
404         /// Concatenates `other` to the end of `self`.
405         ///
406         /// If successful, `other` will be set to 0 and a successful status is returned.
407         ///
408         /// If not successful, `other` will be unchanged and an error is returned.
409         #[diplomat::rust_link(fixed_decimal::FixedDecimal::concatenate_end, FnInStruct)]
410         #[diplomat::rust_link(fixed_decimal::FixedDecimal::concatenated_end, FnInStruct, hidden)]
411         pub fn concatenate_end(&mut self, other: &mut ICU4XFixedDecimal) -> Result<(), ()> {
412             let x = core::mem::take(&mut other.0);
413             self.0.concatenate_end(x).map_err(|y| {
414                 other.0 = y;
415             })
416         }
418         /// Format the [`ICU4XFixedDecimal`] as a string.
419         #[diplomat::rust_link(fixed_decimal::FixedDecimal::write_to, FnInStruct)]
420         #[diplomat::attr(supports = stringifiers, stringifier)]
421         pub fn to_string(&self, to: &mut diplomat_runtime::DiplomatWriteable) {
422             let _ = self.0.write_to(to);
423         }
424     }
427 impl From<ffi::ICU4XFixedDecimalSign> for Sign {
428     fn from(other: ffi::ICU4XFixedDecimalSign) -> Self {
429         match other {
430             ffi::ICU4XFixedDecimalSign::None => Self::None,
431             ffi::ICU4XFixedDecimalSign::Negative => Self::Negative,
432             ffi::ICU4XFixedDecimalSign::Positive => Self::Positive,
433         }
434     }
437 impl From<Sign> for ffi::ICU4XFixedDecimalSign {
438     fn from(other: Sign) -> Self {
439         match other {
440             Sign::None => Self::None,
441             Sign::Negative => Self::Negative,
442             Sign::Positive => Self::Positive,
443         }
444     }
447 impl From<ffi::ICU4XFixedDecimalSignDisplay> for SignDisplay {
448     fn from(other: ffi::ICU4XFixedDecimalSignDisplay) -> Self {
449         match other {
450             ffi::ICU4XFixedDecimalSignDisplay::Auto => Self::Auto,
451             ffi::ICU4XFixedDecimalSignDisplay::Never => Self::Never,
452             ffi::ICU4XFixedDecimalSignDisplay::Always => Self::Always,
453             ffi::ICU4XFixedDecimalSignDisplay::ExceptZero => Self::ExceptZero,
454             ffi::ICU4XFixedDecimalSignDisplay::Negative => Self::Negative,
455         }
456     }
459 impl From<ffi::ICU4XRoundingIncrement> for RoundingIncrement {
460     fn from(value: ffi::ICU4XRoundingIncrement) -> Self {
461         match value {
462             ffi::ICU4XRoundingIncrement::MultiplesOf1 => RoundingIncrement::MultiplesOf1,
463             ffi::ICU4XRoundingIncrement::MultiplesOf2 => RoundingIncrement::MultiplesOf2,
464             ffi::ICU4XRoundingIncrement::MultiplesOf5 => RoundingIncrement::MultiplesOf5,
465             ffi::ICU4XRoundingIncrement::MultiplesOf25 => RoundingIncrement::MultiplesOf25,
466         }
467     }