diff options
author | vallentin <mail@vallentin.dev> | 2021-02-22 04:05:44 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2021-02-22 13:50:09 +0100 |
commit | fb080df3ed384454be4f07a9bf9785194b7f5097 (patch) | |
tree | 99aaed6529b72060159e130404f30383f0ddced1 | |
parent | 7609f00c4b70fa78d2d3e532e786989e719abc18 (diff) | |
download | askama-fb080df3ed384454be4f07a9bf9785194b7f5097.tar.gz askama-fb080df3ed384454be4f07a9bf9785194b7f5097.tar.bz2 askama-fb080df3ed384454be4f07a9bf9785194b7f5097.zip |
Fixed path parser to account for single identifier type names
-rw-r--r-- | askama_shared/src/parser.rs | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs index b91934b..ef88e50 100644 --- a/askama_shared/src/parser.rs +++ b/askama_shared/src/parser.rs @@ -70,7 +70,7 @@ impl Expr<'_> { // The result of a call likely doesn't need to be borrowed, // as in that case the call is more likely to return a // reference in the first place then. - VarCall(..) | PathCall(..) | MethodCall(..) => true, + VarCall(..) | Path(..) | PathCall(..) | MethodCall(..) => true, // If the `expr` is within a `Unary` or `BinOp` then // an assumption can be made that the operand is copy. // If not, then the value is moved and adding `.clone()` @@ -356,12 +356,28 @@ 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, (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)) + + match tuple((root, identifier, ws(tag("::")), tail))(i) { + Ok((i, (root, start, _, rest))) => { + let mut path = Vec::new(); + path.extend(root); + path.push(start); + path.extend(rest); + Ok((i, path)) + } + 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) { + return Ok((i, vec![name])); + } + } + + // If `identifier()` fails then just return the original error + Err(err) + } + } } fn expr_path(i: &[u8]) -> IResult<&[u8], Expr> { |