aboutsummaryrefslogtreecommitdiffstats
path: root/askama_shared
diff options
context:
space:
mode:
authorLibravatar vallentin <mail@vallentin.dev>2021-02-22 04:05:44 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2021-02-22 13:50:09 +0100
commitfb080df3ed384454be4f07a9bf9785194b7f5097 (patch)
tree99aaed6529b72060159e130404f30383f0ddced1 /askama_shared
parent7609f00c4b70fa78d2d3e532e786989e719abc18 (diff)
downloadaskama-fb080df3ed384454be4f07a9bf9785194b7f5097.tar.gz
askama-fb080df3ed384454be4f07a9bf9785194b7f5097.tar.bz2
askama-fb080df3ed384454be4f07a9bf9785194b7f5097.zip
Fixed path parser to account for single identifier type names
Diffstat (limited to 'askama_shared')
-rw-r--r--askama_shared/src/parser.rs30
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> {