mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-28 13:30:59 +00:00
Add support for tuple
This commit is contained in:
parent
39e08325c0
commit
bef88f1696
@ -468,11 +468,7 @@ impl<'a> Generator<'a> {
|
||||
|
||||
self.write_buf_writable(buf);
|
||||
buf.write("for (_loop_index, ");
|
||||
let targets = self.visit_target(var);
|
||||
for name in &targets {
|
||||
self.locals.insert(name);
|
||||
buf.write(name);
|
||||
}
|
||||
self.visit_target(buf, var);
|
||||
match iter {
|
||||
Expr::Range(_, _, _) => buf.writeln(&format!(") in ({}).enumerate() {{", expr_code)),
|
||||
_ => buf.writeln(&format!(") in (&{}).into_iter().enumerate() {{", expr_code)),
|
||||
@ -576,6 +572,15 @@ impl<'a> Generator<'a> {
|
||||
self.locals.insert(name);
|
||||
buf.write(name);
|
||||
}
|
||||
Target::Tuple(ref targets) => {
|
||||
buf.write("(");
|
||||
for name in targets {
|
||||
self.locals.insert(name);
|
||||
buf.write(name);
|
||||
buf.write(",");
|
||||
}
|
||||
buf.write(")");
|
||||
}
|
||||
}
|
||||
buf.writeln(";");
|
||||
}
|
||||
@ -593,6 +598,15 @@ impl<'a> Generator<'a> {
|
||||
}
|
||||
buf.write(name);
|
||||
}
|
||||
Target::Tuple(ref targets) => {
|
||||
buf.write("let (");
|
||||
for name in targets {
|
||||
self.locals.insert(name);
|
||||
buf.write(name);
|
||||
buf.write(",");
|
||||
}
|
||||
buf.write(")");
|
||||
}
|
||||
}
|
||||
buf.writeln(&format!(" = {};", &expr_buf.buf));
|
||||
}
|
||||
@ -1024,13 +1038,21 @@ impl<'a> Generator<'a> {
|
||||
DisplayWrap::Unwrapped
|
||||
}
|
||||
|
||||
fn visit_target_single<'t>(&mut self, name: &'t str) -> Vec<&'t str> {
|
||||
vec![name]
|
||||
}
|
||||
|
||||
fn visit_target<'t>(&mut self, target: &'t Target) -> Vec<&'t str> {
|
||||
fn visit_target(&mut self, buf: &mut Buffer, target: &'a Target) {
|
||||
match *target {
|
||||
Target::Name(s) => self.visit_target_single(s),
|
||||
Target::Name(name) => {
|
||||
self.locals.insert(name);
|
||||
buf.write(name);
|
||||
}
|
||||
Target::Tuple(ref targets) => {
|
||||
buf.write("(");
|
||||
for name in targets {
|
||||
self.locals.insert(name);
|
||||
buf.write(name);
|
||||
buf.write(",");
|
||||
}
|
||||
buf.write(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ pub enum MatchParameter<'a> {
|
||||
#[derive(Debug)]
|
||||
pub enum Target<'a> {
|
||||
Name(&'a str),
|
||||
Tuple(Vec<&'a str>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@ -275,6 +276,25 @@ named!(target_single<Input, Target>, map!(identifier,
|
||||
|s| Target::Name(s)
|
||||
));
|
||||
|
||||
named!(target_tuple<Input, Target>, do_parse!(
|
||||
tag!("(") >>
|
||||
args: opt!(do_parse!(
|
||||
arg0: ws!(identifier) >>
|
||||
args: many0!(do_parse!(
|
||||
tag!(",") >>
|
||||
argn: ws!(identifier) >>
|
||||
(argn)
|
||||
)) >>
|
||||
({
|
||||
let mut res = vec![arg0];
|
||||
res.extend(args);
|
||||
res
|
||||
})
|
||||
)) >>
|
||||
tag!(")") >>
|
||||
(Target::Tuple(args.unwrap_or_default()))
|
||||
));
|
||||
|
||||
named!(variant_name<Input, MatchVariant>, map!(identifier,
|
||||
|s| MatchVariant::Name(s)
|
||||
));
|
||||
@ -703,7 +723,7 @@ named_args!(block_match<'a>(s: &'a Syntax<'a>) <Input<'a>, Node<'a>>, do_parse!(
|
||||
named!(block_let<Input, Node>, do_parse!(
|
||||
pws: opt!(tag!("-")) >>
|
||||
ws!(tag!("let")) >>
|
||||
var: ws!(target_single) >>
|
||||
var: ws!(alt!(target_single | target_tuple)) >>
|
||||
val: opt!(do_parse!(
|
||||
ws!(tag!("=")) >>
|
||||
val: ws!(expr_any) >>
|
||||
@ -720,7 +740,7 @@ named!(block_let<Input, Node>, do_parse!(
|
||||
named_args!(block_for<'a>(s: &'a Syntax<'a>) <Input<'a>, Node<'a>>, do_parse!(
|
||||
pws1: opt!(tag!("-")) >>
|
||||
ws!(tag!("for")) >>
|
||||
var: ws!(target_single) >>
|
||||
var: ws!(alt!(target_single | target_tuple)) >>
|
||||
ws!(tag!("in")) >>
|
||||
iter: ws!(expr_any) >>
|
||||
nws1: opt!(tag!("-")) >>
|
||||
|
@ -1,3 +1,6 @@
|
||||
{% for s in strings %}
|
||||
{{- loop.index0 }}. {{ s }}{% if loop.first %} (first){% endif %}
|
||||
{% endfor %}
|
||||
{% for (s1, s2) in tuple_strings %}
|
||||
{{- loop.index0 }}. {{ s1 }},{{ s2 }}{% if loop.first %} (first){% endif %}
|
||||
{% endfor %}
|
||||
|
@ -1 +1,2 @@
|
||||
{% let v = s %}{{ v }}
|
||||
{% let (v1,v2) = t %}{{ v1 }}{{ v2 }}
|
@ -4,14 +4,19 @@ use askama::Template;
|
||||
#[template(path = "for.html")]
|
||||
struct ForTemplate<'a> {
|
||||
strings: Vec<&'a str>,
|
||||
tuple_strings: Vec<(&'a str, &'a str)>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_for() {
|
||||
let s = ForTemplate {
|
||||
strings: vec!["A", "alfa", "1"],
|
||||
tuple_strings: vec![("B", "beta")],
|
||||
};
|
||||
assert_eq!(s.render().unwrap(), "0. A (first)\n1. alfa\n2. 1\n");
|
||||
assert_eq!(
|
||||
s.render().unwrap(),
|
||||
"0. A (first)\n1. alfa\n2. 1\n\n0. B,beta (first)\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
|
@ -12,6 +12,22 @@ fn test_let() {
|
||||
assert_eq!(t.render().unwrap(), "foo");
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "let.html")]
|
||||
struct LetTupleTemplate<'a> {
|
||||
s: &'a str,
|
||||
t: (&'a str, &'a str),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_let_tuple() {
|
||||
let t = LetTupleTemplate {
|
||||
s: "foo",
|
||||
t: ("bar", "bazz"),
|
||||
};
|
||||
assert_eq!(t.render().unwrap(), "foo\nbarbazz");
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "let-decl.html")]
|
||||
struct LetDeclTemplate<'a> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user