Make splices a bit nicer to use
This commit is contained in:
parent
40424e283c
commit
2250c2e961
2 changed files with 58 additions and 11 deletions
|
@ -11,6 +11,9 @@ use super::render::{Escape, Renderer};
|
|||
macro_rules! dollar {
|
||||
() => (TtToken(_, token::Dollar))
|
||||
}
|
||||
macro_rules! dot {
|
||||
() => (TtToken(_, token::Dot))
|
||||
}
|
||||
macro_rules! eq {
|
||||
() => (TtToken(_, token::Eq))
|
||||
}
|
||||
|
@ -125,17 +128,34 @@ impl<'cx, 's, 'i, 'r, 'o> Parser<'cx, 's, 'i, 'r, 'o> {
|
|||
}
|
||||
|
||||
fn splice(&mut self, escape: Escape, sp: Span) {
|
||||
let tt = match self.input {
|
||||
[ref tt, ..] => {
|
||||
self.shift(1);
|
||||
self.new_rust_parser(vec![tt.clone()]).parse_expr()
|
||||
},
|
||||
_ => {
|
||||
self.render.cx.span_err(sp, "expected expression for this splice");
|
||||
return;
|
||||
},
|
||||
};
|
||||
self.render.splice(tt, escape);
|
||||
let mut tts = vec![];
|
||||
// First, munch a single token tree
|
||||
if let [ref tt, ..] = self.input {
|
||||
self.shift(1);
|
||||
tts.push(tt.clone());
|
||||
}
|
||||
loop {
|
||||
match self.input {
|
||||
// Munch attribute lookups e.g. `$person.address.street`
|
||||
[ref dot @ dot!(), ref ident @ ident!(_), ..] => {
|
||||
self.shift(2);
|
||||
tts.push(dot.clone());
|
||||
tts.push(ident.clone());
|
||||
},
|
||||
// Munch function calls `()` and indexing operations `[]`
|
||||
[TtDelimited(sp, ref d), ..] if d.delim != token::DelimToken::Brace => {
|
||||
self.shift(1);
|
||||
tts.push(TtDelimited(sp, d.clone()));
|
||||
},
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
if tts.is_empty() {
|
||||
self.render.cx.span_err(sp, "expected expression for this splice");
|
||||
} else {
|
||||
let expr = self.new_rust_parser(tts).parse_expr();
|
||||
self.render.splice(expr, escape);
|
||||
}
|
||||
}
|
||||
|
||||
fn element(&mut self, name: &str, sp: Span) {
|
||||
|
|
|
@ -123,6 +123,33 @@ mod splices {
|
|||
assert_eq!(s, "Pinkie Pie");
|
||||
}
|
||||
|
||||
/// An example struct, for testing purposes only
|
||||
struct Creature {
|
||||
name: &'static str,
|
||||
/// Rating out of 10, where:
|
||||
/// * 0 is a naked mole rat with dysentery
|
||||
/// * 10 is Sweetie Belle in a milkshake
|
||||
adorableness: u8,
|
||||
}
|
||||
|
||||
impl Creature {
|
||||
fn repugnance(&self) -> u8 {
|
||||
10 - self.adorableness
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn structs() {
|
||||
let pinkie = Creature {
|
||||
name: "Pinkie Pie",
|
||||
adorableness: 9,
|
||||
};
|
||||
let s = html! {
|
||||
"Name: " $pinkie.name ". Rating: " $pinkie.repugnance()
|
||||
}.render();
|
||||
assert_eq!(s, "Name: Pinkie Pie. Rating: 1");
|
||||
}
|
||||
|
||||
// FIXME: See <https://github.com/rust-lang/rust/issues/16617>
|
||||
// for why this is commented out
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue