Merge pull request #55 from utkarshkukreti/while
Add support for `@while` and `@while let`.
This commit is contained in:
commit
9ff5ff4f2c
3 changed files with 58 additions and 0 deletions
maud_macros
|
@ -142,6 +142,11 @@ impl<'cx, 'a, 'i> Parser<'cx, 'a, 'i> {
|
||||||
self.shift(2);
|
self.shift(2);
|
||||||
self.if_expr(sp)?;
|
self.if_expr(sp)?;
|
||||||
},
|
},
|
||||||
|
// While
|
||||||
|
[at!(), keyword!(sp, k), ..] if k.is_keyword(keywords::While) => {
|
||||||
|
self.shift(2);
|
||||||
|
self.while_expr(sp)?;
|
||||||
|
},
|
||||||
// For
|
// For
|
||||||
[at!(), keyword!(sp, k), ..] if k.is_keyword(keywords::For) => {
|
[at!(), keyword!(sp, k), ..] if k.is_keyword(keywords::For) => {
|
||||||
self.shift(2);
|
self.shift(2);
|
||||||
|
@ -248,6 +253,28 @@ impl<'cx, 'a, 'i> Parser<'cx, 'a, 'i> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses and renders an `@while` expression.
|
||||||
|
///
|
||||||
|
/// The leading `@while` should already be consumed.
|
||||||
|
fn while_expr(&mut self, sp: Span) -> PResult<()> {
|
||||||
|
let mut cond = vec![];
|
||||||
|
let body;
|
||||||
|
loop { match *self.input {
|
||||||
|
[TokenTree::Delimited(sp, ref d), ..] if d.delim == DelimToken::Brace => {
|
||||||
|
self.shift(1);
|
||||||
|
body = self.block(sp, &d.tts)?;
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
[ref tt, ..] => {
|
||||||
|
self.shift(1);
|
||||||
|
cond.push(tt.clone());
|
||||||
|
},
|
||||||
|
[] => parse_error!(self, sp, "expected body for this @while"),
|
||||||
|
}}
|
||||||
|
self.render.emit_while(cond, body);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses and renders a `@for` expression.
|
/// Parses and renders a `@for` expression.
|
||||||
///
|
///
|
||||||
/// The leading `@for` should already be consumed.
|
/// The leading `@for` should already be consumed.
|
||||||
|
|
|
@ -138,6 +138,15 @@ impl<'cx, 'a> Renderer<'cx, 'a> {
|
||||||
self.push(stmt);
|
self.push(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Emits an `while` expression.
|
||||||
|
///
|
||||||
|
/// The condition is a token tree (not an expression) so we don't
|
||||||
|
/// need to special-case `while let`.
|
||||||
|
pub fn emit_while(&mut self, cond: Vec<TokenTree>, body: Vec<Stmt>) {
|
||||||
|
let stmt = quote_stmt!(self.cx, while $cond { $body }).unwrap();
|
||||||
|
self.push(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn emit_for(&mut self, pattern: P<Pat>, iterable: P<Expr>, body: Vec<Stmt>) {
|
pub fn emit_for(&mut self, pattern: P<Pat>, iterable: P<Expr>, body: Vec<Stmt>) {
|
||||||
let stmt = quote_stmt!(self.cx, for $pattern in $iterable { $body }).unwrap();
|
let stmt = quote_stmt!(self.cx, for $pattern in $iterable { $body }).unwrap();
|
||||||
self.push(stmt);
|
self.push(stmt);
|
||||||
|
|
|
@ -35,6 +35,28 @@ fn if_let() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn while_expr() {
|
||||||
|
let mut numbers = (0..3).into_iter().peekable();
|
||||||
|
let s = html! {
|
||||||
|
ul @while numbers.peek().is_some() {
|
||||||
|
li (numbers.next().unwrap())
|
||||||
|
}
|
||||||
|
}.into_string();
|
||||||
|
assert_eq!(s, "<ul><li>0</li><li>1</li><li>2</li></ul>");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn while_let_expr() {
|
||||||
|
let mut numbers = (0..3).into_iter();
|
||||||
|
let s = html! {
|
||||||
|
ul @while let Some(n) = numbers.next() {
|
||||||
|
li (n)
|
||||||
|
}
|
||||||
|
}.into_string();
|
||||||
|
assert_eq!(s, "<ul><li>0</li><li>1</li><li>2</li></ul>");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn for_expr() {
|
fn for_expr() {
|
||||||
let ponies = ["Apple Bloom", "Scootaloo", "Sweetie Belle"];
|
let ponies = ["Apple Bloom", "Scootaloo", "Sweetie Belle"];
|
||||||
|
|
Loading…
Add table
Reference in a new issue