diff --git a/examples/form-controls.rs b/examples/form-controls.rs index e793cb73..e2c7dc43 100644 --- a/examples/form-controls.rs +++ b/examples/form-controls.rs @@ -12,7 +12,7 @@ impl Extension for FormControls { } fn configure_router(&self, router: Router) -> Router { - router.route("/", web::get(form_controls).post(form_controls)) + router.route("/", web::get(form_controls)) } } diff --git a/src/locale/lc.rs b/src/locale/lc.rs index 551a8f4f..c54ed4fb 100644 --- a/src/locale/lc.rs +++ b/src/locale/lc.rs @@ -12,8 +12,6 @@ use std::collections::HashMap; use std::fmt; -// **< LcKind >************************************************************************************* - // Tipo de localización a aplicar. // // * `None` - No se aplica ninguna localización. @@ -27,31 +25,6 @@ enum LcKind { Translate(CowStr), } -// **< LcArg >************************************************************************************** - -// Valor de un argumento de la traducción. -// -// `Text` resuelve a `FluentValue::String` para interpolar cualquier texto; pero no aplica el -// selector de plural de Fluent (`{ $n -> [one] ... *[other] ... }`). Para eso está `Number`, que -// resuelve a `FluentValue::Number` y es el único tipo con el que Fluent consulta las reglas de -// plural del idioma. -#[derive(Clone, Debug)] -enum LcArg { - Text(CowStr), - Number(u32), -} - -impl<'a> From<&'a LcArg> for fluent_templates::fluent_bundle::FluentValue<'a> { - fn from(arg: &'a LcArg) -> Self { - match arg { - LcArg::Text(s) => s.as_ref().into(), - LcArg::Number(n) => (*n).into(), - } - } -} - -// **< Lc >***************************************************************************************** - /// Crea instancias para traducir *textos localizados*. /// /// Cada instancia puede representar: @@ -108,7 +81,7 @@ pub struct Lc { op: LcKind, #[default(&LOCALES_PAGETOP)] locales: &'static Locales, - args: Vec<(CowStr, LcArg)>, + args: Vec<(CowStr, CowStr)>, } impl fmt::Debug for Lc { @@ -168,46 +141,22 @@ impl Lc { // **< Lc BUILDER >***************************************************************************** /// Añade un argumento `{$arg}` => `value` a la traducción. - /// - /// `value` se interpreta siempre como texto. Si se necesita un argumento numérico que además - /// deba seleccionar plural (`{ $n -> [one] ... *[other] ... }`), hay que utilizar en su lugar - /// [`with_number()`](Self::with_number). pub fn with_arg(mut self, arg: impl Into, value: impl Into) -> Self { - self.args.push((arg.into(), LcArg::Text(value.into()))); + self.args.push((arg.into(), value.into())); self } - /// Añade varios argumentos de texto a la traducción de una vez (p. ej. usando la macro + /// Añade varios argumentos a la traducción de una vez (p. ej. usando la macro /// [`util::kv!`](crate::util::kv) o también `vec![("k", "v")]`, incluso un array de duplas u - /// otras colecciones). Aplica sólo a texto, como [`with_arg()`](Self::with_arg). + /// otras colecciones). pub fn with_args(mut self, args: I) -> Self where I: IntoIterator, K: Into, V: Into, { - self.args.extend( - args.into_iter() - .map(|(k, v)| (k.into(), LcArg::Text(v.into()))), - ); - self - } - - /// Añade un argumento numérico `{$arg}` => `n` a la traducción. - /// - /// A diferencia de [`with_arg()`](Self::with_arg), `n` se interpola como un número real, el - /// único tipo en el que Fluent aplica las reglas de plural del idioma para que un selector - /// `{ $n -> [one] ... *[other] ... }` elija correctamente entre singular y plural. - /// - /// # Ejemplo - /// - /// ```rust,no_run - /// # use pagetop::prelude::*; - /// // "1 año" / "3 años", según el idioma y el valor de `n`. - /// let text = Lc::l("years_count").with_number("n", 3).get(); - /// ``` - pub fn with_number(mut self, arg: impl Into, n: u32) -> Self { - self.args.push((arg.into(), LcArg::Number(n))); + self.args + .extend(args.into_iter().map(|(k, v)| (k.into(), v.into()))); self } @@ -262,7 +211,7 @@ impl Lc { } else { let mut args = HashMap::with_capacity(self.args.len()); for (k, v) in self.args.iter() { - args.insert(k.clone(), v.into()); + args.insert(k.clone(), v.as_ref().into()); } self.locales .try_lookup_with_args(language.langid(), key.as_ref(), &args) diff --git a/tests/locale.rs b/tests/locale.rs index ca55fd92..11f08def 100644 --- a/tests/locale.rs +++ b/tests/locale.rs @@ -43,27 +43,12 @@ async fn translation_with_plural_and_select() { assert!(translation.contains("añadido 3 nuevas fotos de él")); } -// `with_arg()` only interpolates text: `photoCount` as a string ("3") can never select the `[one]` -// plural branch, whatever its value. Only `with_number()` produces a real numeric argument that -// Fluent's plural rules can match against. -#[pagetop::test] -async fn translation_with_number_selects_the_singular_plural_branch() { - setup().await; - - let lc = Lc::l("test_shared_photos") - .with_arg("userName", "Roberto") - .with_number("photoCount", 1) - .with_arg("userGender", "male"); - let translation = lc.lookup(&Locale::resolve("es-ES")).unwrap(); - assert!(translation.contains("ha añadido una nueva foto de él")); -} - #[pagetop::test] async fn check_fallback_language() { setup().await; let lc = Lc::l("test_hello_world"); - let translation = lc.lookup(&Locale::resolve("xx-YY")); // Falls back to "en-US". + let translation = lc.lookup(&Locale::resolve("xx-YY")); // Retrocede a "en-US". assert_eq!(translation, Some("Hello world!".to_string())); }