Add number truncation before back-end translation (#3162)

* Add number-truncation before backend translation

* Round instead of truncate (conform to testcases)

* Add test-case for plural rounding-to-one corner-case

* Move rounding into generated translation code

* Change unit test to test generated function

* Round any number in generation, ignore (int vs float)

(it seems that that type distinction is frequently inaccurate)

* Update formatting
This commit is contained in:
Lucas Scharenbroch 2024-04-23 20:41:40 -05:00 committed by GitHub
parent 2c9accf595
commit ee8683587a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 49 additions and 8 deletions

View File

@ -22,13 +22,46 @@ type FluentBundle<T> = FluentBundleOrig<T, intl_memoizer::concurrent::IntlLangMe
pub use fluent::fluent_args as tr_args;
pub trait Number: Into<FluentNumber> {}
impl Number for i32 {}
impl Number for i64 {}
impl Number for u32 {}
impl Number for f32 {}
impl Number for u64 {}
impl Number for usize {}
pub trait Number: Into<FluentNumber> {
fn round(self) -> Self;
}
impl Number for i32 {
#[inline]
fn round(self) -> Self {
self
}
}
impl Number for i64 {
#[inline]
fn round(self) -> Self {
self
}
}
impl Number for u32 {
#[inline]
fn round(self) -> Self {
self
}
}
impl Number for f32 {
// round to 2 decimal places
#[inline]
fn round(self) -> Self {
(self * 100.0).round() / 100.0
}
}
impl Number for u64 {
#[inline]
fn round(self) -> Self {
self
}
}
impl Number for usize {
#[inline]
fn round(self) -> Self {
self
}
}
fn remapped_lang_name(lang: &LanguageIdentifier) -> &str {
let region = lang.region.as_ref().map(|v| v.as_str());
@ -446,6 +479,14 @@ mod test {
assert!(want_comma_as_decimal_separator(&[langid!("pl-PL")]));
}
#[test]
fn decimal_rounding() {
let tr = I18n::new(&["en"]);
assert_eq!(tr.browsing_cards_deleted(1.001), "1 card deleted.");
assert_eq!(tr.browsing_cards_deleted(1.01), "1.01 cards deleted.");
}
#[test]
fn i18n() {
// English template

View File

@ -97,7 +97,7 @@ fn build_vars(translation: &Translation) -> String {
let rust_name = v.name.to_snake_case();
let trailer = match v.kind {
VariableKind::Any => "",
VariableKind::Int | VariableKind::Float => ".into()",
VariableKind::Int | VariableKind::Float => ".round().into()",
VariableKind::String => ".into()",
};
writeln!(