From 5a799af0900882414b2cf5e642e88a3e36845400 Mon Sep 17 00:00:00 2001 From: vallentin Date: Tue, 23 Feb 2021 08:48:37 +0100 Subject: Reworked constants to be parsed as paths --- askama_shared/src/generator.rs | 7 ++----- askama_shared/src/parser.rs | 30 ++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) (limited to 'askama_shared/src') diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index e74de14..b4363a8 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -1723,11 +1723,8 @@ impl MapChain<'_, &str, LocalMeta> { } fn resolve_or_self(&self, name: &str) -> String { - match self.resolve(name) { - Some(name) => name, - None if name.chars().any(char::is_uppercase) => name.to_string(), - None => format!("self.{}", name), - } + self.resolve(name) + .unwrap_or_else(|| format!("self.{}", name)) } } diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs index df3ee8f..ea13738 100644 --- a/askama_shared/src/parser.rs +++ b/askama_shared/src/parser.rs @@ -367,9 +367,11 @@ fn path(i: &[u8]) -> IResult<&[u8], Vec<&str>> { } Err(err) => { if let Ok((i, name)) = identifier(i) { - // If the returned identifier contains both a lowercase and uppercase - // character, then we assume it's a type name, e.g. `Some`. - if name.contains(char::is_uppercase) && name.contains(char::is_lowercase) { + // The returned identifier can be assumed to be path if: + // - Contains both a lowercase and uppercase character, i.e. a type name like `None` + // - Doesn't contain any lowercase characters, i.e. it's a constant + // In short, if it contains any uppercase characters it's a path. + if name.contains(char::is_uppercase) { return Ok((i, vec![name])); } } @@ -1235,17 +1237,32 @@ mod tests { vec![Node::Expr(Ws(false, false), Expr::Var("foo"))], ); assert_eq!( - super::parse("{{ FOO }}", &s).unwrap(), - vec![Node::Expr(Ws(false, false), Expr::Var("FOO"))], + super::parse("{{ foo_bar }}", &s).unwrap(), + vec![Node::Expr(Ws(false, false), Expr::Var("foo_bar"))], ); assert_eq!( super::parse("{{ none }}", &s).unwrap(), vec![Node::Expr(Ws(false, false), Expr::Var("none"))], ); + } + + #[test] + fn test_parse_const() { + let s = Syntax::default(); + + assert_eq!( + super::parse("{{ FOO }}", &s).unwrap(), + vec![Node::Expr(Ws(false, false), Expr::Path(vec!["FOO"]))], + ); + assert_eq!( + super::parse("{{ FOO_BAR }}", &s).unwrap(), + vec![Node::Expr(Ws(false, false), Expr::Path(vec!["FOO_BAR"]))], + ); + assert_eq!( super::parse("{{ NONE }}", &s).unwrap(), - vec![Node::Expr(Ws(false, false), Expr::Var("NONE"))], + vec![Node::Expr(Ws(false, false), Expr::Path(vec!["NONE"]))], ); } @@ -1264,6 +1281,7 @@ mod tests { Expr::PathCall(vec!["Some"], vec![Expr::NumLit("123")],), )], ); + assert_eq!( super::parse("{{ Ok(123) }}", &s).unwrap(), vec![Node::Expr( -- cgit