parent
2e0aa3e433
commit
34f14dd41d
2 changed files with 35 additions and 2 deletions
|
@ -55,6 +55,9 @@ macro_rules! literal {
|
||||||
macro_rules! ident {
|
macro_rules! ident {
|
||||||
($sp:pat, $x:pat) => (TtToken($sp, Token::Ident($x, IdentStyle::Plain)))
|
($sp:pat, $x:pat) => (TtToken($sp, Token::Ident($x, IdentStyle::Plain)))
|
||||||
}
|
}
|
||||||
|
macro_rules! substnt {
|
||||||
|
($sp:pat, $x:pat) => (TtToken($sp, Token::SubstNt($x, IdentStyle::Plain)))
|
||||||
|
}
|
||||||
macro_rules! keyword {
|
macro_rules! keyword {
|
||||||
($sp:pat, $x:ident) => (TtToken($sp, ref $x @ Token::Ident(..)))
|
($sp:pat, $x:ident) => (TtToken($sp, ref $x @ Token::Ident(..)))
|
||||||
}
|
}
|
||||||
|
@ -167,6 +170,14 @@ impl<'cx, 'i> Parser<'cx, 'i> {
|
||||||
let expr = try!(self.splice(tt.get_span()));
|
let expr = try!(self.splice(tt.get_span()));
|
||||||
self.render.splice(expr);
|
self.render.splice(expr);
|
||||||
},
|
},
|
||||||
|
[substnt!(sp, ident), ..] => {
|
||||||
|
self.shift(1);
|
||||||
|
// Parse `SubstNt` as `[Dollar, Ident]`
|
||||||
|
// See <https://github.com/lfairy/maud/issues/23>
|
||||||
|
let prefix = TtToken(sp, Token::Ident(ident, IdentStyle::Plain));
|
||||||
|
let expr = try!(self.splice_with_prefix(prefix));
|
||||||
|
self.render.splice(expr);
|
||||||
|
},
|
||||||
// Element
|
// Element
|
||||||
[ident!(sp, _), ..] => {
|
[ident!(sp, _), ..] => {
|
||||||
let name = try!(self.name());
|
let name = try!(self.name());
|
||||||
|
@ -295,13 +306,20 @@ impl<'cx, 'i> Parser<'cx, 'i> {
|
||||||
/// The leading `$` should already be consumed.
|
/// The leading `$` should already be consumed.
|
||||||
fn splice(&mut self, sp: Span) -> PResult<P<Expr>> {
|
fn splice(&mut self, sp: Span) -> PResult<P<Expr>> {
|
||||||
// First, munch a single token tree
|
// First, munch a single token tree
|
||||||
let mut tts = match self.input {
|
let prefix = match self.input {
|
||||||
[ref tt, ..] => {
|
[ref tt, ..] => {
|
||||||
self.shift(1);
|
self.shift(1);
|
||||||
vec![tt.clone()]
|
tt.clone()
|
||||||
},
|
},
|
||||||
[] => parse_error!(self, sp, "expected expression for this splice"),
|
[] => parse_error!(self, sp, "expected expression for this splice"),
|
||||||
};
|
};
|
||||||
|
self.splice_with_prefix(prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parses and renders a `$splice`, given a prefix that we've already
|
||||||
|
/// consumed.
|
||||||
|
fn splice_with_prefix(&mut self, prefix: TokenTree) -> PResult<P<Expr>> {
|
||||||
|
let mut tts = vec![prefix];
|
||||||
loop { match self.input {
|
loop { match self.input {
|
||||||
// Munch attribute lookups e.g. `$person.address.street`
|
// Munch attribute lookups e.g. `$person.address.street`
|
||||||
[ref dot @ dot!(), ref ident @ ident!(_, _), ..] => {
|
[ref dot @ dot!(), ref ident @ ident!(_, _), ..] => {
|
||||||
|
|
|
@ -294,3 +294,18 @@ fn call() {
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
assert_eq!(s, "DucksGeeseSwans");
|
assert_eq!(s, "DucksGeeseSwans");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn issue_23() {
|
||||||
|
macro_rules! to_string {
|
||||||
|
($($x:tt)*) => {{
|
||||||
|
let mut s = String::new();
|
||||||
|
html!(s, $($x)*).unwrap();
|
||||||
|
s
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = "Lyra";
|
||||||
|
let s = to_string!(p { "Hi, " $name "!" });
|
||||||
|
assert_eq!(s, "<p>Hi, Lyra!</p>");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue