• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ).
4 
5 #[diplomat::bridge]
6 #[diplomat::abi_rename = "icu4x_{0}_mv1"]
7 #[diplomat::attr(auto, namespace = "icu4x")]
8 pub mod ffi {
9     use alloc::boxed::Box;
10 
11     #[cfg(feature = "buffer_provider")]
12     use crate::errors::ffi::DataError;
13     #[cfg(feature = "buffer_provider")]
14     use crate::provider::ffi::DataProvider;
15 
16     #[diplomat::opaque]
17     /// An ICU4X Units Converter Factory object, capable of creating converters a [`UnitsConverter`]
18     /// for converting between two [`MeasureUnit`]s.
19     ///
20     /// Also, it can parse the CLDR unit identifier (e.g. `meter-per-square-second`) and get the [`MeasureUnit`].
21     #[diplomat::rust_link(icu::experimental::units::converter_factory::ConverterFactory, Struct)]
22     pub struct UnitsConverterFactory(
23         pub icu_experimental::units::converter_factory::ConverterFactory,
24     );
25 
26     impl UnitsConverterFactory {
27         /// Construct a new [`UnitsConverterFactory`] instance using compiled data.
28         #[diplomat::rust_link(
29             icu::experimental::units::converter_factory::ConverterFactory::new,
30             FnInStruct
31         )]
32         #[diplomat::attr(auto, constructor)]
33         #[cfg(feature = "compiled_data")]
create() -> Box<UnitsConverterFactory>34         pub fn create() -> Box<UnitsConverterFactory> {
35             Box::new(UnitsConverterFactory(
36                 icu_experimental::units::converter_factory::ConverterFactory::new(),
37             ))
38         }
39         /// Construct a new [`UnitsConverterFactory`] instance using a particular data source.
40         #[diplomat::rust_link(
41             icu::experimental::units::converter_factory::ConverterFactory::new,
42             FnInStruct
43         )]
44         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
45         #[cfg(feature = "buffer_provider")]
create_with_provider( provider: &DataProvider, ) -> Result<Box<UnitsConverterFactory>, DataError>46         pub fn create_with_provider(
47             provider: &DataProvider,
48         ) -> Result<Box<UnitsConverterFactory>, DataError> {
49             Ok(Box::new(UnitsConverterFactory(icu_experimental::units::converter_factory::ConverterFactory::try_new_with_buffer_provider(provider.get()?)?)))
50         }
51         /// Creates a new [`UnitsConverter`] from the input and output [`MeasureUnit`]s.
52         /// Returns nothing if the conversion between the two units is not possible.
53         /// For example, conversion between `meter` and `second` is not possible.
54         #[diplomat::rust_link(
55             icu::experimental::units::converter_factory::ConverterFactory::converter,
56             FnInStruct
57         )]
converter( &self, from: &MeasureUnit, to: &MeasureUnit, ) -> Option<Box<UnitsConverter>>58         pub fn converter(
59             &self,
60             from: &MeasureUnit,
61             to: &MeasureUnit,
62         ) -> Option<Box<UnitsConverter>> {
63             self.0
64                 .converter(&from.0, &to.0)
65                 .map(UnitsConverter)
66                 .map(Box::new)
67         }
68 
69         /// Creates a parser to parse the CLDR unit identifier (e.g. `meter-per-square-second`) and get the [`MeasureUnit`].
70         #[diplomat::rust_link(
71             icu::experimental::units::converter_factory::ConverterFactory::parser,
72             FnInStruct
73         )]
parser<'a>(&'a self) -> Box<MeasureUnitParser<'a>>74         pub fn parser<'a>(&'a self) -> Box<MeasureUnitParser<'a>> {
75             MeasureUnitParser(self.0.parser()).into()
76         }
77     }
78 
79     #[diplomat::opaque]
80     /// An ICU4X Measurement Unit parser object which is capable of parsing the CLDR unit identifier
81     /// (e.g. `meter-per-square-second`) and get the [`MeasureUnit`].
82     #[diplomat::rust_link(icu::experimental::measure::parser::MeasureUnitParser, Struct)]
83     pub struct MeasureUnitParser<'a>(pub icu_experimental::measure::parser::MeasureUnitParser<'a>);
84 
85     impl<'a> MeasureUnitParser<'a> {
86         /// Parses the CLDR unit identifier (e.g. `meter-per-square-second`) and returns the corresponding [`MeasureUnit`],
87         /// if the identifier is valid.
88         #[diplomat::rust_link(
89             icu::experimental::measure::parser::MeasureUnitParser::parse,
90             FnInStruct
91         )]
parse(&self, unit_id: &DiplomatStr) -> Option<Box<MeasureUnit>>92         pub fn parse(&self, unit_id: &DiplomatStr) -> Option<Box<MeasureUnit>> {
93             self.0
94                 .try_from_utf8(unit_id)
95                 .ok()
96                 .map(MeasureUnit)
97                 .map(Box::new)
98         }
99     }
100 
101     #[diplomat::opaque]
102     /// An ICU4X Measurement Unit object which represents a single unit of measurement
103     /// such as `meter`, `second`, `kilometer-per-hour`, `square-meter`, etc.
104     ///
105     /// You can create an instance of this object using [`MeasureUnitParser`] by calling the `parse_measure_unit` method.
106     #[diplomat::rust_link(icu::experimental::measure::measureunit::MeasureUnit, Struct)]
107     pub struct MeasureUnit(pub icu_experimental::measure::measureunit::MeasureUnit);
108 
109     #[diplomat::opaque]
110     /// An ICU4X Units Converter object, capable of converting between two [`MeasureUnit`]s.
111     ///
112     /// You can create an instance of this object using [`UnitsConverterFactory`] by calling the `converter` method.
113     #[diplomat::rust_link(icu::experimental::units::converter::UnitsConverter, Struct)]
114     pub struct UnitsConverter(pub icu_experimental::units::converter::UnitsConverter<f64>);
115     impl UnitsConverter {
116         /// Converts the input value from the input unit to the output unit (that have been used to create this converter).
117         /// NOTE:
118         ///   The conversion using floating-point operations is not as accurate as the conversion using ratios.
119         #[diplomat::rust_link(
120             icu::experimental::units::converter::UnitsConverter::convert,
121             FnInStruct
122         )]
123         #[diplomat::attr(supports = method_overloading, rename = "convert")]
124         #[diplomat::attr(js, rename = "convert_number")]
convert_double(&self, value: f64) -> f64125         pub fn convert_double(&self, value: f64) -> f64 {
126             self.0.convert(&value)
127         }
128 
129         /// Clones the current [`UnitsConverter`] object.
130         #[diplomat::rust_link(
131             icu::experimental::units::converter::UnitsConverter::clone,
132             FnInStruct
133         )]
clone(&self) -> Box<Self>134         pub fn clone(&self) -> Box<Self> {
135             Box::new(UnitsConverter(self.0.clone()))
136         }
137     }
138 }
139