Skip to content

Commit

Permalink
Merge pull request #6 from LeoniePhiline/i18n
Browse files Browse the repository at this point in the history
fix: Implement missing recursive `is_cachable()` for `Expr::Localize`
  • Loading branch information
89Q12 authored Oct 11, 2022
2 parents 8f30ba5 + 6cda9f5 commit 9e1f326
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 18 deletions.
4 changes: 2 additions & 2 deletions askama/src/i18n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ impl Locale<'_> {

pub fn translate<'a>(
&self,
text_id: &str,
msg_id: &str,
args: impl IntoIterator<Item = (&'a str, FluentValue<'a>)>,
) -> Option<String> {
let args = HashMap::<&str, FluentValue<'_>>::from_iter(args);
let args = match args.is_empty() {
true => None,
false => Some(&args),
};
self.loader.lookup_complete(&self.language, text_id, args)
self.loader.lookup_complete(&self.language, msg_id, args)
}
}

Expand Down
8 changes: 4 additions & 4 deletions askama_derive/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1292,15 +1292,15 @@ impl<'a> Generator<'a> {
Expr::Try(ref expr) => self.visit_try(buf, expr.as_ref())?,
Expr::Tuple(ref exprs) => self.visit_tuple(buf, exprs)?,
#[cfg(feature = "i18n")]
Expr::Localize(ref message, ref args) => self.visit_localize(buf, message, args)?,
Expr::Localize(ref msg_id, ref args) => self.visit_localize(buf, msg_id, args)?,
})
}

#[cfg(feature = "i18n")]
fn visit_localize(
&mut self,
buf: &mut Buffer,
message: &Expr<'_>,
msg_id: &Expr<'_>,
args: &[(&str, Expr<'_>)],
) -> Result<DisplayWrap, CompileError> {
let localizer =
Expand All @@ -1312,7 +1312,7 @@ impl<'a> Generator<'a> {
"self.{}.translate(",
normalize_identifier(localizer)
));
self.visit_expr(buf, message)?;
self.visit_expr(buf, msg_id)?;
buf.writeln(", [")?;
buf.indent();
for (k, v) in args {
Expand All @@ -1321,7 +1321,7 @@ impl<'a> Generator<'a> {
buf.writeln(")),")?;
}
buf.dedent()?;
// Safe to unwrap, as `message` is checked at compile time.
// Safe to unwrap, as `msg_id` is checked at compile time.
buf.write("]).unwrap()");

Ok(DisplayWrap::Unwrapped)
Expand Down
6 changes: 3 additions & 3 deletions askama_derive/src/i18n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ pub(crate) fn load(input: TokenStream) -> Result<TokenStream, CompileError> {
Ok(ts.into())
}

pub(crate) fn arguments_of(text_id: &str) -> Result<HashSet<&'static str>, CompileError> {
pub(crate) fn arguments_of(msg_id: &str) -> Result<HashSet<&'static str>, CompileError> {
let config = get_i18n_config()?;
let entry = config.fallbacks[&config.fallback]
.iter()
Expand All @@ -303,8 +303,8 @@ pub(crate) fn arguments_of(text_id: &str) -> Result<HashSet<&'static str>, Compi
fluent_syntax::ast::Entry::Message(entry) => Some(entry),
_ => None,
})
.find(|entry| entry.id.name == text_id)
.ok_or_else(|| CompileError::from(format!("text_id {:?} not found", text_id)))?;
.find(|entry| entry.id.name == msg_id)
.ok_or_else(|| CompileError::from(format!("msg_id {:?} not found", msg_id)))?;

let keys = entry
.value
Expand Down
15 changes: 9 additions & 6 deletions askama_derive/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ impl Expr<'_> {
}
Expr::Group(arg) => arg.is_cachable(),
Expr::Tuple(args) => args.iter().all(|arg| arg.is_cachable()),
Expr::Localize(msg_id, args) => {
msg_id.is_cachable() && args.iter().all(|(_, arg)| arg.is_cachable())
}
// We have too little information to tell if the expression is pure:
Expr::Call(_, _) => false,
Expr::RustMacro(_, _) => false,
Expand Down Expand Up @@ -731,14 +734,14 @@ fn expr_localize(i: &str) -> IResult<&str, Expr<'_>> {
Ok((i, args))
}

let (j, (_, _, (text_id, args, _))) = tuple((
let (j, (_, _, (msg_id, args, _))) = tuple((
tag("localize"),
ws(tag("(")),
cut(tuple((expr_any, localize_args, ws(tag(")"))))),
))(i)?;

if let Expr::StrLit(text_id) = text_id {
let mut msg_args = match crate::i18n::arguments_of(text_id) {
if let Expr::StrLit(msg_id) = msg_id {
let mut msg_args = match crate::i18n::arguments_of(msg_id) {
Ok(args) => args,
Err(err) => {
eprintln!("{}", err.msg);
Expand All @@ -749,21 +752,21 @@ fn expr_localize(i: &str) -> IResult<&str, Expr<'_>> {
if !msg_args.remove(call_arg) {
eprintln!(
"Fluent template {:?} does not contain argument {:?}",
text_id, call_arg,
msg_id, call_arg,
);
return Err(nom::Err::Failure(error_position!(i, ErrorKind::Tag)));
}
}
if !msg_args.is_empty() {
eprintln!(
"Missing argument(s) {:?} to fluent template {:?}",
msg_args, text_id,
msg_args, msg_id,
);
return Err(nom::Err::Failure(error_position!(i, ErrorKind::Tag)));
}
}

Ok((j, Expr::Localize(text_id.into(), args)))
Ok((j, Expr::Localize(msg_id.into(), args)))
}

expr_prec_layer!(expr_muldivmod, expr_filtered, "*", "/", "%");
Expand Down
6 changes: 3 additions & 3 deletions testing/tests/i18n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct UsesNoArgsI18n<'a> {
}

#[test]
fn existing_language() {
fn test_existing_language() {
let template = UsesI18n {
loc: Locale::new(langid!("es-MX"), &LOCALES),
name: "Hilda",
Expand All @@ -36,7 +36,7 @@ fn existing_language() {
}

#[test]
fn fallback_language() {
fn test_fallback_language() {
let template = UsesI18n {
loc: Locale::new(langid!("nl-BE"), &LOCALES),
name: "Hilda",
Expand All @@ -50,7 +50,7 @@ fn fallback_language() {
}

#[test]
fn no_args() {
fn test_no_args() {
let template = UsesNoArgsI18n {
loc: Locale::new(langid!("en-US"), &LOCALES),
};
Expand Down

0 comments on commit 9e1f326

Please sign in to comment.