From fa9404872efa17012f1991c1865d3db75debeda7 Mon Sep 17 00:00:00 2001 From: Chris Wong <lambda.fairy@gmail.com> Date: Mon, 9 Feb 2015 15:05:50 +1300 Subject: [PATCH] Refactor toggleable attributes --- maud_macros/src/parse.rs | 19 +++++++++++++++++-- maud_macros/src/render.rs | 28 +++++++++++----------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs index aaa2a2a..84d674e 100644 --- a/maud_macros/src/parse.rs +++ b/maud_macros/src/parse.rs @@ -1,4 +1,4 @@ -use syntax::ast::{Expr, Lit, Stmt, TokenTree, TtDelimited, TtToken}; +use syntax::ast::{Expr, ExprParen, Lit, Stmt, TokenTree, TtDelimited, TtToken}; use syntax::codemap::Span; use syntax::ext::base::ExtCtxt; use syntax::parse; @@ -207,7 +207,14 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> { // Toggle the attribute based on a boolean expression self.shift(1); let cond = self.splice(tt.get_span()); - self.render.attribute_empty_if(name.as_str(), cond); + // Silence "unnecessary parentheses" warnings + let cond = strip_outer_parens(cond); + let body = { + let mut r = self.render.fork(); + r.attribute_empty(name.as_str()); + r.into_stmts() + }; + self.render.emit_if(cond, body, None); } else { // Write the attribute unconditionally self.render.attribute_empty(name.as_str()); @@ -249,3 +256,11 @@ fn lit_to_string(cx: &ExtCtxt, lit: Lit, minus: bool) -> Option<String> { }; Some(result) } + +/// If the expression is wrapped in parentheses, strip them off. +fn strip_outer_parens(expr: P<Expr>) -> P<Expr> { + expr.and_then(|expr| match expr { + Expr { node: ExprParen(inner), .. } => inner, + expr => P(expr), + }) +} diff --git a/maud_macros/src/render.rs b/maud_macros/src/render.rs index dc87d24..9b3a97c 100644 --- a/maud_macros/src/render.rs +++ b/maud_macros/src/render.rs @@ -1,5 +1,5 @@ use std::borrow::IntoCow; -use syntax::ast::{Expr, ExprParen, Ident, Stmt}; +use syntax::ast::{Expr, Ident, Stmt}; use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::parse::token; @@ -112,22 +112,6 @@ impl<'cx, 's> Renderer<'cx, 's> { self.write(name); } - pub fn attribute_empty_if(&mut self, name: &str, cond: P<Expr>) { - // Silence "unnecessary parentheses" warnings - let cond = match cond.node { - ExprParen(ref inner) => inner.clone(), - _ => cond.clone(), - }; - let body = { - let mut r = self.fork(); - r.write(" "); - r.write(name); - r.into_stmts() - }; - let stmt = quote_stmt!(self.cx, if $cond { $body }); - self.stmts.push(stmt); - } - pub fn attribute_end(&mut self) { self.write("\""); } @@ -141,4 +125,14 @@ impl<'cx, 's> Renderer<'cx, 's> { self.write(name); self.write(">"); } + + pub fn emit_if(&mut self, cond: P<Expr>, if_body: Vec<P<Stmt>>, + else_body: Option<Vec<P<Stmt>>>) { + let stmt = match else_body { + None => quote_stmt!(self.cx, if $cond { $if_body }), + Some(else_body) => + quote_stmt!(self.cx, if $cond { $if_body } else { $else_body }), + }; + self.stmts.push(stmt); + } }