From 810d5ad5067085cc5e4be19903b5804b1ff13430 Mon Sep 17 00:00:00 2001 From: Christian Vallentin Date: Wed, 2 Dec 2020 20:46:29 +0100 Subject: Allow paths to start with `::` (#393) --- askama_shared/src/parser.rs | 29 +++++++++++++++++++++++++---- testing/tests/simple.rs | 9 +++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs index 7224d02..8210ed0 100644 --- a/askama_shared/src/parser.rs +++ b/askama_shared/src/parser.rs @@ -1,7 +1,7 @@ use nom::branch::alt; use nom::bytes::complete::{escaped, is_not, tag, take_until}; use nom::character::complete::{anychar, char, digit1}; -use nom::combinator::{complete, map, opt}; +use nom::combinator::{complete, map, opt, value}; use nom::error::ParseError; use nom::multi::{many0, many1, separated_list0, separated_list1}; use nom::sequence::{delimited, pair, tuple}; @@ -312,10 +312,12 @@ fn expr_var_call(i: &[u8]) -> IResult<&[u8], Expr> { } fn path(i: &[u8]) -> IResult<&[u8], Vec<&str>> { + let root = opt(value("", ws(tag("::")))); let tail = separated_list1(ws(tag("::")), identifier); - let (i, (start, _, rest)) = tuple((identifier, ws(tag("::")), tail))(i)?; - - let mut path = vec![start]; + let (i, (root, start, _, rest)) = tuple((root, identifier, ws(tag("::")), tail))(i)?; + let mut path = Vec::new(); + path.extend(root); + path.push(start); path.extend(rest); Ok((i, path)) } @@ -1136,6 +1138,25 @@ mod tests { ); } + #[test] + fn test_parse_root_path() { + let syntax = Syntax::default(); + assert_eq!( + super::parse("{{ std::string::String::new() }}", &syntax).unwrap(), + vec![Node::Expr( + WS(false, false), + Expr::PathCall(vec!["std", "string", "String", "new"], vec![]), + )], + ); + assert_eq!( + super::parse("{{ ::std::string::String::new() }}", &syntax).unwrap(), + vec![Node::Expr( + WS(false, false), + Expr::PathCall(vec!["", "std", "string", "String", "new"], vec![]), + )], + ); + } + #[test] fn change_delimiters_parse_filter() { let syntax = Syntax { diff --git a/testing/tests/simple.rs b/testing/tests/simple.rs index 7241005..5ef03b1 100644 --- a/testing/tests/simple.rs +++ b/testing/tests/simple.rs @@ -290,6 +290,15 @@ fn test_path_func_call() { assert_eq!(PathFunctionTemplate.render().unwrap(), "Hello, world4123!"); } +#[derive(Template)] +#[template(source = "{{ ::std::string::ToString::to_string(123) }}", ext = "txt")] +struct RootPathFunctionTemplate; + +#[test] +fn test_root_path_func_call() { + assert_eq!(RootPathFunctionTemplate.render().unwrap(), "123"); +} + #[derive(Template)] #[template(source = "Hello, {{ Self::world3(self, \"123\", 4) }}!", ext = "txt")] struct FunctionTemplate; -- cgit