projectfluent / fluent-rs

Rust implementation of Project Fluent
https://projectfluent.org
Apache License 2.0
1.04k stars 96 forks source link

Support full precision of all numbers #337

Open Urgau opened 5 months ago

Urgau commented 5 months ago

When using fluent inside the Rust compiler we came across an unfortunate limitation, fluent and more precisely FluentNumber doesn't support the full precision of all numbers it accepts.

https://github.com/projectfluent/fluent-rs/blob/a2cef6bff4885623f638a6968e034ce1a296ba01/fluent-bundle/src/types/number.rs#L125-L129

This is due to the internal representation of number which uses a f64 which can't fully represent a i64 and u64. For example i64::MAX (9223372036854775807) would be 92233720368547760000, notice the last 4 character 5807 != 0000.

This is particularly a problem for rustc because we print the limits of numbers, which would be off if done using f64. We workaround it using a string for numbers between -100..=100 (to still be able to select on them); but this isn't a solution.


One way I could see fluent fix this issue would be to use a representation like this:

#[derive(Debug, PartialEq, Clone)]
pub enum FluentNumberValue {
    Float(f64),
    SignedInteger(i128),
    UnsignedInteger(u128),
}
JasperDeSutter commented 1 month ago

This could probably be solved by using https://docs.rs/fixed_decimal/0.5.5/fixed_decimal as the number representation, which supports arbitrary precision. Combined with the open PRs to switch to ICU4X for plurals and number formatting, it should also remove the lossy internal conversion from f64 to FixedDecimal.