Fit more values into DiagnosticArgValue::Number.

It contains an `i128`, but when creating them we convert any number
outside the range -100..100 to a string, because Fluent uses an `f64`.
It's all a bit strange.

This commit changes the `i128` to an `i32`, which fits safely in
Fluent's `f64`, and removes the -100..100 range check. This means that
only integers outside the range of `i32` will be converted to strings.
This commit is contained in:
Nicholas Nethercote 2024-01-30 14:46:51 +11:00
parent 3db37fb78a
commit 26eb6da4e7
2 changed files with 6 additions and 7 deletions

View File

@ -33,7 +33,10 @@
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
pub enum DiagnosticArgValue {
Str(Cow<'static, str>),
Number(i128),
// This gets converted to a `FluentNumber`, which is an `f64`. An `i32`
// safely fits in an `f64`. Any integers bigger than that will be converted
// to strings in `into_diagnostic_arg` and stored using the `Str` variant.
Number(i32),
StrListSepByAnd(Vec<Cow<'static, str>>),
}

View File

@ -63,12 +63,8 @@ macro_rules! into_diagnostic_arg_for_number {
$(
impl IntoDiagnosticArg for $ty {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
// HACK: `FluentNumber` the underline backing struct represent
// numbers using a f64 which can't represent all the i128 numbers
// So in order to be able to use fluent selectors and still
// have all the numbers representable we only convert numbers
// below a certain threshold.
if let Ok(n) = TryInto::<i128>::try_into(self) && n >= -100 && n <= 100 {
// Convert to a string if it won't fit into `Number`.
if let Ok(n) = TryInto::<i32>::try_into(self) {
DiagnosticArgValue::Number(n)
} else {
self.to_string().into_diagnostic_arg()