diff --git a/rslib/i18n/build/extract.rs b/rslib/i18n/build/extract.rs index f28c43d58..eee5ba0b8 100644 --- a/rslib/i18n/build/extract.rs +++ b/rslib/i18n/build/extract.rs @@ -165,9 +165,11 @@ impl From for Variable { | "kilobytes" | "daysStart" | "daysEnd" | "days" | "secs-per-card" | "remaining" | "hourStart" | "hourEnd" | "correct" => VariableKind::Int, "average-seconds" | "cards-per-minute" => VariableKind::Float, - "val" | "found" | "expected" | "part" | "percent" | "day" => VariableKind::Any, + "val" | "found" | "expected" | "part" | "percent" | "day" | "number" | "up" + | "down" | "seconds" | "megs" => VariableKind::Any, term => { - if term.ends_with("Count") || term.ends_with("Secs") { + let term = term.to_ascii_lowercase(); + if term.ends_with("count") { VariableKind::Int } else { VariableKind::String diff --git a/rslib/i18n/build/write_strings.rs b/rslib/i18n/build/write_strings.rs index 219080a03..5b15fe99d 100644 --- a/rslib/i18n/build/write_strings.rs +++ b/rslib/i18n/build/write_strings.rs @@ -7,7 +7,7 @@ use inflections::Inflect; use std::{fmt::Write, fs, path::PathBuf}; use crate::{ - extract::{Module, Translation}, + extract::{Module, Translation, VariableKind}, gather::{TranslationsByFile, TranslationsByLang}, }; @@ -31,9 +31,8 @@ pub fn write_strings(map: &TranslationsByLang, modules: &[Module]) { fn write_methods(modules: &[Module], buf: &mut String) { buf.push_str( r#" -use crate::I18n; -use crate::tr_args; -use fluent::FluentValue; +use crate::{I18n,Number}; +use fluent::{FluentValue, FluentArgs}; use std::borrow::Cow; impl I18n { @@ -46,12 +45,15 @@ impl I18n { let doc = translation.text.replace("\n", " "); let in_args; let out_args; + let var_build; if translation.variables.is_empty() { in_args = "".to_string(); out_args = ", None".to_string(); + var_build = "".to_string(); } else { in_args = build_in_args(translation); - out_args = build_out_args(translation); + var_build = build_vars(translation); + out_args = ", Some(args)".to_string(); } writeln!( @@ -60,6 +62,7 @@ impl I18n { /// {doc} #[inline] pub fn {func}<'a>(&'a self{in_args}) -> Cow<'a, str> {{ +{var_build} self.translate("{key}"{out_args}) }}"#, func = func, @@ -67,6 +70,7 @@ impl I18n { doc = doc, in_args = in_args, out_args = out_args, + var_build = var_build, ) .unwrap(); } @@ -75,19 +79,35 @@ impl I18n { buf.push_str("}\n"); } -fn build_out_args(translation: &Translation) -> String { - let v: Vec<_> = translation - .variables - .iter() - .map(|var| { - format!( - r#""{fluent_name}"=>{rust_name}"#, - fluent_name = var.name, - rust_name = var.name.to_snake_case() +fn build_vars(translation: &Translation) -> String { + if translation.variables.is_empty() { + "let args = None;\n".into() + } else { + let mut buf = String::from( + r#" + let mut args = FluentArgs::new(); +"#, + ); + for v in &translation.variables { + let fluent_name = &v.name; + let rust_name = v.name.to_snake_case(); + let trailer = match v.kind { + VariableKind::Any => "", + VariableKind::Int | VariableKind::Float => ".into()", + VariableKind::String => ".into()", + }; + writeln!( + buf, + r#" args.set("{fluent_name}", {rust_name}{trailer});"#, + fluent_name = fluent_name, + rust_name = rust_name, + trailer = trailer, ) - }) - .collect(); - format!(", Some(tr_args![{}])", v.join(", ")) + .unwrap(); + } + + buf + } } fn build_in_args(translation: &Translation) -> String { @@ -95,13 +115,13 @@ fn build_in_args(translation: &Translation) -> String { .variables .iter() .map(|var| { - // let kind = match var.kind { - // VariableKind::Int => "i64", - // VariableKind::Float => "f64", - // VariableKind::String => "&str", - // VariableKind::Any => "&str", - // }; - let kind = "impl Into>"; + let kind = match var.kind { + VariableKind::Int => "impl Number", + VariableKind::Float => "impl Number", + VariableKind::String => "impl Into", + // VariableKind::Any => "&str", + _ => "impl Into>", + }; format!("{}: {}", var.name.to_snake_case(), kind) }) .collect(); diff --git a/rslib/i18n/src/lib.rs b/rslib/i18n/src/lib.rs index fc3762979..38a1fd49d 100644 --- a/rslib/i18n/src/lib.rs +++ b/rslib/i18n/src/lib.rs @@ -3,7 +3,7 @@ mod generated; -use fluent::{FluentArgs, FluentResource, FluentValue}; +use fluent::{types::FluentNumber, FluentArgs, FluentResource, FluentValue}; use fluent_bundle::bundle::FluentBundle as FluentBundleOrig; use num_format::Locale; use serde::Serialize; @@ -17,6 +17,14 @@ type FluentBundle = FluentBundleOrig {} +impl Number for i32 {} +impl Number for i64 {} +impl Number for u32 {} +impl Number for f32 {} +impl Number for u64 {} +impl Number for usize {} + fn remapped_lang_name(lang: &LanguageIdentifier) -> &str { let region = match &lang.region { Some(region) => Some(region.as_str()),