Support if let

This commit is contained in:
Chris Wong 2015-03-15 16:23:19 +13:00
parent 098e71468c
commit 333eb46c3a
3 changed files with 24 additions and 6 deletions
maud_macros

View file

@ -1,5 +1,6 @@
use std::mem;
use syntax::ast::{Expr, ExprParen, Lit, Stmt, TokenTree, TtDelimited, TtToken};
use syntax::ext::quote::rt::ToTokens;
use syntax::codemap::Span;
use syntax::ext::base::ExtCtxt;
use syntax::parse;
@ -152,7 +153,7 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
fn if_expr(&mut self, sp: Span) {
// Parse the initial if
let mut cond_tts = vec![];
let mut if_cond = vec![];
let if_body;
loop { match self.input {
[TtDelimited(sp, ref d), ..] if d.delim == DelimToken::Brace => {
@ -162,11 +163,10 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
},
[ref tt, ..] => {
self.shift(1);
cond_tts.push(tt.clone());
if_cond.push(tt.clone());
},
[] => self.render.cx.span_fatal(sp, "expected body for this $if"),
}}
let if_cond = self.new_rust_parser(cond_tts).parse_expr();
// Parse the (optional) else
let else_body = match self.input {
[dollar!(), ident!(else_), ..] if else_.as_str() == "else" => {
@ -298,7 +298,7 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
self.shift(1);
let cond = self.splice(tt.get_span());
// Silence "unnecessary parentheses" warnings
let cond = strip_outer_parens(cond);
let cond = strip_outer_parens(cond).to_tokens(self.render.cx);
let body = {
let mut r = self.render.fork();
r.attribute_empty(name.as_str());

View file

@ -1,4 +1,4 @@
use syntax::ast::{Expr, Ident, Pat, Stmt};
use syntax::ast::{Expr, Ident, Pat, Stmt, TokenTree};
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
@ -126,7 +126,11 @@ impl<'cx, 's> Renderer<'cx, 's> {
self.write(">");
}
pub fn emit_if(&mut self, if_cond: P<Expr>, if_body: Vec<P<Stmt>>,
/// Emit an `if` expression.
///
/// The condition is a token tree (not an expression) so we don't
/// need to special-case `if let`.
pub fn emit_if(&mut self, if_cond: Vec<TokenTree>, if_body: Vec<P<Stmt>>,
else_body: Option<Vec<P<Stmt>>>) {
let stmt = match else_body {
None => quote_stmt!(self.cx, if $if_cond { $if_body }),

View file

@ -202,6 +202,20 @@ mod control {
}
}
#[test]
fn if_let() {
for &(input, output) in [(Some("yay"), "yay"), (None, "oh noes")].iter() {
let s = html! {
$if let Some(value) = input {
$value
} $else {
"oh noes"
}
}.to_string();
assert_eq!(s, output);
}
}
#[test]
fn for_expr() {
let ponies = ["Apple Bloom", "Scootaloo", "Sweetie Belle"];