mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-28 05:21:14 +00:00
parser: introduce askama_parser::expr::Range
This commit is contained in:
parent
9f882e2ca7
commit
49d4397f51
@ -76,8 +76,8 @@ impl<'a> Generator<'a, '_> {
|
|||||||
}) => self.visit_filter(ctx, buf, name, arguments, generics, expr.span())?,
|
}) => self.visit_filter(ctx, buf, name, arguments, generics, expr.span())?,
|
||||||
Expr::Unary(op, ref inner) => self.visit_unary(ctx, buf, op, inner)?,
|
Expr::Unary(op, ref inner) => self.visit_unary(ctx, buf, op, inner)?,
|
||||||
Expr::BinOp(ref v) => self.visit_binop(ctx, buf, v.op, &v.lhs, &v.rhs)?,
|
Expr::BinOp(ref v) => self.visit_binop(ctx, buf, v.op, &v.lhs, &v.rhs)?,
|
||||||
Expr::Range(op, ref left, ref right) => {
|
Expr::Range(ref v) => {
|
||||||
self.visit_range(ctx, buf, op, left.as_deref(), right.as_deref())?
|
self.visit_range(ctx, buf, v.op, v.lhs.as_ref(), v.rhs.as_ref())?
|
||||||
}
|
}
|
||||||
Expr::Group(ref inner) => self.visit_group(ctx, buf, inner)?,
|
Expr::Group(ref inner) => self.visit_group(ctx, buf, inner)?,
|
||||||
Expr::Call {
|
Expr::Call {
|
||||||
|
@ -199,7 +199,7 @@ impl<'a> Generator<'a, '_> {
|
|||||||
| Expr::Attr(_, _)
|
| Expr::Attr(_, _)
|
||||||
| Expr::Index(_, _)
|
| Expr::Index(_, _)
|
||||||
| Expr::Filter(_)
|
| Expr::Filter(_)
|
||||||
| Expr::Range(_, _, _)
|
| Expr::Range(_)
|
||||||
| Expr::Call { .. }
|
| Expr::Call { .. }
|
||||||
| Expr::RustMacro(_, _)
|
| Expr::RustMacro(_, _)
|
||||||
| Expr::Try(_)
|
| Expr::Try(_)
|
||||||
@ -1649,9 +1649,8 @@ fn is_cacheable(expr: &WithSpan<'_, Expr<'_>>) -> bool {
|
|||||||
Expr::Unary(_, arg) => is_cacheable(arg),
|
Expr::Unary(_, arg) => is_cacheable(arg),
|
||||||
Expr::BinOp(v) => is_cacheable(&v.lhs) && is_cacheable(&v.rhs),
|
Expr::BinOp(v) => is_cacheable(&v.lhs) && is_cacheable(&v.rhs),
|
||||||
Expr::IsDefined(_) | Expr::IsNotDefined(_) => true,
|
Expr::IsDefined(_) | Expr::IsNotDefined(_) => true,
|
||||||
Expr::Range(_, lhs, rhs) => {
|
Expr::Range(v) => {
|
||||||
lhs.as_ref().is_none_or(|v| is_cacheable(v))
|
v.lhs.as_ref().is_none_or(is_cacheable) && v.rhs.as_ref().is_none_or(is_cacheable)
|
||||||
&& rhs.as_ref().is_none_or(|v| is_cacheable(v))
|
|
||||||
}
|
}
|
||||||
Expr::Group(arg) => is_cacheable(arg),
|
Expr::Group(arg) => is_cacheable(arg),
|
||||||
Expr::Tuple(args) => args.iter().all(is_cacheable),
|
Expr::Tuple(args) => args.iter().all(is_cacheable),
|
||||||
|
@ -101,11 +101,11 @@ fn check_expr<'a>(expr: &WithSpan<'a, Expr<'a>>, allowed: Allowed) -> Result<(),
|
|||||||
check_expr(&v.lhs, Allowed::default())?;
|
check_expr(&v.lhs, Allowed::default())?;
|
||||||
check_expr(&v.rhs, Allowed::default())
|
check_expr(&v.rhs, Allowed::default())
|
||||||
}
|
}
|
||||||
Expr::Range(_, elem1, elem2) => {
|
Expr::Range(v) => {
|
||||||
if let Some(elem1) = elem1 {
|
if let Some(elem1) = v.lhs.as_ref() {
|
||||||
check_expr(elem1, Allowed::default())?;
|
check_expr(elem1, Allowed::default())?;
|
||||||
}
|
}
|
||||||
if let Some(elem2) = elem2 {
|
if let Some(elem2) = v.rhs.as_ref() {
|
||||||
check_expr(elem2, Allowed::default())?;
|
check_expr(elem2, Allowed::default())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -170,11 +170,7 @@ pub enum Expr<'a> {
|
|||||||
NamedArgument(&'a str, Box<WithSpan<'a, Expr<'a>>>),
|
NamedArgument(&'a str, Box<WithSpan<'a, Expr<'a>>>),
|
||||||
Unary(&'a str, Box<WithSpan<'a, Expr<'a>>>),
|
Unary(&'a str, Box<WithSpan<'a, Expr<'a>>>),
|
||||||
BinOp(Box<BinOp<'a>>),
|
BinOp(Box<BinOp<'a>>),
|
||||||
Range(
|
Range(Box<Range<'a>>),
|
||||||
&'a str,
|
|
||||||
Option<Box<WithSpan<'a, Expr<'a>>>>,
|
|
||||||
Option<Box<WithSpan<'a, Expr<'a>>>>,
|
|
||||||
),
|
|
||||||
Group(Box<WithSpan<'a, Expr<'a>>>),
|
Group(Box<WithSpan<'a, Expr<'a>>>),
|
||||||
Tuple(Vec<WithSpan<'a, Expr<'a>>>),
|
Tuple(Vec<WithSpan<'a, Expr<'a>>>),
|
||||||
Call {
|
Call {
|
||||||
@ -196,6 +192,13 @@ pub enum Expr<'a> {
|
|||||||
ArgumentPlaceholder,
|
ArgumentPlaceholder,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Range<'a> {
|
||||||
|
pub op: &'a str,
|
||||||
|
pub lhs: Option<WithSpan<'a, Expr<'a>>>,
|
||||||
|
pub rhs: Option<WithSpan<'a, Expr<'a>>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct BinOp<'a> {
|
pub struct BinOp<'a> {
|
||||||
pub op: &'a str,
|
pub op: &'a str,
|
||||||
@ -300,12 +303,23 @@ impl<'a> Expr<'a> {
|
|||||||
};
|
};
|
||||||
let expr = alt((
|
let expr = alt((
|
||||||
range_right.map(move |(op, right)| {
|
range_right.map(move |(op, right)| {
|
||||||
WithSpan::new(Self::Range(op, None, right.map(Box::new)), start)
|
WithSpan::new(
|
||||||
|
Self::Range(Box::new(Range {
|
||||||
|
op,
|
||||||
|
lhs: None,
|
||||||
|
rhs: right,
|
||||||
|
})),
|
||||||
|
start,
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
(move |i: &mut _| Self::or(i, level), opt(range_right)).map(move |(left, right)| {
|
(move |i: &mut _| Self::or(i, level), opt(range_right)).map(move |(left, right)| {
|
||||||
match right {
|
match right {
|
||||||
Some((op, right)) => WithSpan::new(
|
Some((op, right)) => WithSpan::new(
|
||||||
Self::Range(op, Some(Box::new(left)), right.map(Box::new)),
|
Self::Range(Box::new(Range {
|
||||||
|
op,
|
||||||
|
lhs: Some(left),
|
||||||
|
rhs: right,
|
||||||
|
})),
|
||||||
start,
|
start,
|
||||||
),
|
),
|
||||||
None => left,
|
None => left,
|
||||||
@ -611,7 +625,7 @@ impl<'a> Expr<'a> {
|
|||||||
| Self::RustMacro(_, _)
|
| Self::RustMacro(_, _)
|
||||||
| Self::As(_, _)
|
| Self::As(_, _)
|
||||||
| Self::Call { .. }
|
| Self::Call { .. }
|
||||||
| Self::Range(_, _, _)
|
| Self::Range(_)
|
||||||
| Self::Try(_)
|
| Self::Try(_)
|
||||||
| Self::NamedArgument(_, _)
|
| Self::NamedArgument(_, _)
|
||||||
| Self::Filter(_)
|
| Self::Filter(_)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user