Support if let
This commit is contained in:
parent
098e71468c
commit
333eb46c3a
3 changed files with 24 additions and 6 deletions
|
@ -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());
|
||||
|
|
|
@ -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 }),
|
||||
|
|
|
@ -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"];
|
||||
|
|
Loading…
Add table
Reference in a new issue