parent
a3908faf24
commit
39602a075c
3 changed files with 70 additions and 0 deletions
maud_macros
|
@ -156,6 +156,11 @@ impl<'cx, 'a, 'i> Parser<'cx, 'a, 'i> {
|
|||
self.shift(2);
|
||||
self.match_expr(sp)?;
|
||||
},
|
||||
// Let
|
||||
[at!(), keyword!(sp, k), ..] if k.is_keyword(keywords::Let) => {
|
||||
self.shift(2);
|
||||
self.let_expr(sp)?;
|
||||
}
|
||||
// Element
|
||||
[ident!(sp, _), ..] => {
|
||||
let name = self.namespaced_name().unwrap();
|
||||
|
@ -402,6 +407,42 @@ impl<'cx, 'a, 'i> Parser<'cx, 'a, 'i> {
|
|||
Ok(body)
|
||||
}
|
||||
|
||||
/// Parses and renders a `@let` expression.
|
||||
///
|
||||
/// The leading `@let` should already be consumed.
|
||||
fn let_expr(&mut self, sp: Span) -> PResult<()> {
|
||||
let mut pattern = vec![];
|
||||
loop { match *self.input {
|
||||
[eq!(), ..] => {
|
||||
self.shift(1);
|
||||
break;
|
||||
},
|
||||
[ref tt, ..] => {
|
||||
self.shift(1);
|
||||
pattern.push(tt.clone());
|
||||
},
|
||||
_ => parse_error!(self, sp, "invalid @let"),
|
||||
}}
|
||||
let pattern = self.with_rust_parser(pattern, RustParser::parse_pat)?;
|
||||
let mut rhs = 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);
|
||||
rhs.push(tt.clone());
|
||||
},
|
||||
_ => parse_error!(self, sp, "invalid @let"),
|
||||
}}
|
||||
let rhs = self.with_rust_parser(rhs, RustParser::parse_expr)?;
|
||||
self.render.emit_let(pattern, rhs, body);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses and renders an element node.
|
||||
///
|
||||
/// The element name should already be consumed.
|
||||
|
|
|
@ -156,6 +156,11 @@ impl<'cx, 'a> Renderer<'cx, 'a> {
|
|||
let stmt = quote_stmt!(self.cx, match $match_var { $match_body }).unwrap();
|
||||
self.push(stmt);
|
||||
}
|
||||
|
||||
pub fn emit_let(&mut self, pattern: P<Pat>, rhs: P<Expr>, body: Vec<Stmt>) {
|
||||
let stmt = quote_stmt!(self.cx, { let $pattern = $rhs; $body }).unwrap();
|
||||
self.push(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
fn html_escape(s: &str) -> String {
|
||||
|
|
|
@ -131,3 +131,27 @@ fn match_in_attribute() {
|
|||
assert_eq!(s, output);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_expr() {
|
||||
let s = html! {
|
||||
@let x = 42 {
|
||||
"I have " (x) " cupcakes!"
|
||||
}
|
||||
}.into_string();
|
||||
assert_eq!(s, "I have 42 cupcakes!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_lexical_scope() {
|
||||
let x = 42;
|
||||
let s = html! {
|
||||
@let x = 99 {
|
||||
"Twilight thought I had " (x) " cupcakes, "
|
||||
}
|
||||
"but I only had " (x) "."
|
||||
}.into_string();
|
||||
assert_eq!(s, concat!(
|
||||
"Twilight thought I had 99 cupcakes, ",
|
||||
"but I only had 42."));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue