icu4x
icu4x copied to clipboard
Design for the first version of the units conversion.
I am proposing this design for the fist version of the units conversion.
First MeasureUnit:
- it is a struct that contains a list of
MeasureUnitItems. - Each
MeasureUnitItemcontains the following:
- si prefix --> optional
- unit id
- power
MeasureUnitimplements afn try_from_id(id: &str) --> Result<Self, DimensionError>
Second: Converter
- it is a struct that contains the followings:
- Conversion Rate (including the offset)
- Convertibility
Converterimplements the following functions:
static fn try_from_ids( id1: &str, id2: &str) --> Result<Self, DimensionError>static fn try_from_measunits( unit1: &MeasureUnit, unit2: &MeasureUnit) --> Result<Self, DimensionError>static fn extract_convertibility_from_ids( id1: &str, id2: &str) --> Result<Convertibility, DimensionError>static fn extract_convertibility_from_measunits( unit1: &MeasureUnit, unit2: &MeasureUnit --> Result<Convertibility, DimensionError>fn convert_f64(&self, value: f64) --> f64fn convert_BigRational(&self, value: BigRational) --> BigRationalfn convert_FixedDecimal(&self, value: FixedDecimal) --> FixedDecimal--> postpone for now.
Third: Convertibility
- An
enumthat contains the following fields:
ConvertibleReciprocalNotConvertible??? --> do we need it ?
Fourth: DimensionError
- An
enumthat contains the following fields:
WrongCldrUnitIdNotConvertible
Discussion:
@sffc , for MeasureUnitParser, we can have MeasureUnitParser::parse_bytes(&self, bytes: &[u8]) --> Result<MeasureUnit>
and also MeasureUnitParser::parse_str(&self, id : &str) --> Result<> --> this is an implementation for FromStr trait.
NOTE: we need a MeasureUnitParser that takes the units provider and parse the strings to return MeasureUnit.
Also, for the Converter, we need ConverterFactory
File a TODO issue to split the data between the MeasureUnitParser and ConverterFactory
and start with
5. fn convert_f64(&self, value: f64) --> f64
6. fn convert_big_rational(&self, value: BigRational) --> BigRational
LGTM tentatively : @younies , @sffc , @robertbastian , @Manishearth
Design the FFI for units conersion.
- @younies - On FFI I want to be able to interface with f64.
option 0
Convert(input: IcuRatio) --> IcuRatio.
IcuRatio::from_f64()
IcuRatio::to_f64()
IcuRatio::to_u64()
option 1
Converter::convert_f64(input: f64) --> f64.
Converter::convert_exact(input: IcuRatio) -> IcuRatio
conv.convert_exact(IcuRatio::fraction(7, 3))
conv.convert_exact(IcuRatio::from(7).pow(-4)))
conv.convert_f64(10e-4))
- @robertbastian I prefer this over 0, there's no expectation that convert(123.4) == convert2(IcuRatio::from_u64(123.4)).to_u64()
- @sffc - I like this because we can change the internal of IcuRatio
- @robertbastian - But that's horrible because we can't advertise performance characteristics; we should just use the standard Rust type
pub struct IcuRatio(pub BigRational);
option 2
No IcuRatio on FFI
// String syntax: [-]iii.fffE[-]eee
Converter::convert_decimal(input: string) -> Result<string>
Converter::convert_f64(input: f64) -> f64
Eliminated: the user might want to use IcuRatio across multiple call sites
option 3
Converter::convert_decimal(input: FixedDecimal) -> FixedDecimal
Converter::convert_f64(input: f64) -> f64
Eliminated: FixedDecimal is not efficient for math, and it can't represent ratios like 1/3
option 4
Converter::convert_f64(input: f64) -> f64.
Converter::convert_big_rational(input: BigRational) -> BigRational
conv.convert_big_rational(...)
conv.convert_big_rational(...)
conv.convert_f64(10e-4))
Expose subset of BigRational API over FFI as IcuRational (bikeshed)
- @Manishearth - Not super happy of putting non-ICU4X types on FFI
- @robertbastian - If we want to use standard Rust types in Rust, that's the cost
- @sffc - I'd prefer naming it
ICU4XBigRationalor keeping it in the namespace at least
Note: Ratio<BigInt> has a type alias to BigRational
LGTM: @sffc @robertbastian @younies @Manishearth