units_converter.rs (4489B)
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 crate::unstable::measure_unit_parser::ffi::MeasureUnit; 10 use alloc::boxed::Box; 11 12 #[cfg(feature = "buffer_provider")] 13 use crate::unstable::errors::ffi::DataError; 14 #[cfg(feature = "buffer_provider")] 15 use crate::unstable::provider::ffi::DataProvider; 16 17 #[diplomat::opaque] 18 /// An ICU4X Units Converter Factory object, capable of creating converters a [`UnitsConverter`] 19 /// for converting between two [`MeasureUnit`]s. 20 /// 21 /// Also, it can parse the CLDR unit identifier (e.g. `meter-per-square-second`) and get the [`MeasureUnit`]. 22 #[diplomat::rust_link(icu::experimental::units::converter_factory::ConverterFactory, Struct)] 23 pub struct UnitsConverterFactory( 24 pub icu_experimental::units::converter_factory::ConverterFactory, 25 ); 26 27 impl UnitsConverterFactory { 28 /// Construct a new [`UnitsConverterFactory`] instance using compiled data. 29 #[diplomat::rust_link( 30 icu::experimental::units::converter_factory::ConverterFactory::new, 31 FnInStruct 32 )] 33 #[diplomat::attr(auto, constructor)] 34 #[cfg(feature = "compiled_data")] 35 pub fn create() -> Box<UnitsConverterFactory> { 36 Box::new(UnitsConverterFactory( 37 icu_experimental::units::converter_factory::ConverterFactory::new(), 38 )) 39 } 40 /// Construct a new [`UnitsConverterFactory`] instance using a particular data source. 41 #[diplomat::rust_link( 42 icu::experimental::units::converter_factory::ConverterFactory::new, 43 FnInStruct 44 )] 45 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")] 46 #[cfg(feature = "buffer_provider")] 47 pub fn create_with_provider( 48 provider: &DataProvider, 49 ) -> Result<Box<UnitsConverterFactory>, DataError> { 50 Ok(Box::new(UnitsConverterFactory(icu_experimental::units::converter_factory::ConverterFactory::try_new_with_buffer_provider(provider.get()?)?))) 51 } 52 /// Creates a new [`UnitsConverter`] from the input and output [`MeasureUnit`]s. 53 /// Returns nothing if the conversion between the two units is not possible. 54 /// For example, conversion between `meter` and `second` is not possible. 55 #[diplomat::rust_link( 56 icu::experimental::units::converter_factory::ConverterFactory::converter, 57 FnInStruct 58 )] 59 pub fn converter( 60 &self, 61 from: &MeasureUnit, 62 to: &MeasureUnit, 63 ) -> Option<Box<UnitsConverter>> { 64 self.0 65 .converter(&from.0, &to.0) 66 .map(UnitsConverter) 67 .map(Box::new) 68 } 69 } 70 71 #[diplomat::opaque] 72 /// An ICU4X Units Converter object, capable of converting between two [`MeasureUnit`]s. 73 /// 74 /// You can create an instance of this object using [`UnitsConverterFactory`] by calling the `converter` method. 75 #[diplomat::rust_link(icu::experimental::units::converter::UnitsConverter, Struct)] 76 pub struct UnitsConverter(pub icu_experimental::units::converter::UnitsConverter<f64>); 77 impl UnitsConverter { 78 /// Converts the input value from the input unit to the output unit (that have been used to create this converter). 79 /// NOTE: 80 /// The conversion using floating-point operations is not as accurate as the conversion using ratios. 81 #[diplomat::rust_link( 82 icu::experimental::units::converter::UnitsConverter::convert, 83 FnInStruct 84 )] 85 #[diplomat::attr(supports = method_overloading, rename = "convert")] 86 #[diplomat::attr(js, rename = "convert_number")] 87 pub fn convert_double(&self, value: f64) -> f64 { 88 self.0.convert(&value) 89 } 90 91 /// Clones the current [`UnitsConverter`] object. 92 #[diplomat::rust_link( 93 icu::experimental::units::converter::UnitsConverter::clone, 94 FnInStruct 95 )] 96 pub fn clone(&self) -> Box<Self> { 97 Box::new(UnitsConverter(self.0.clone())) 98 } 99 } 100 }