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 {
|
macro_rules! dollar {
|
||||||
() => (TtToken(_, token::Dollar))
|
() => (TtToken(_, token::Dollar))
|
||||||
}
|
}
|
||||||
|
macro_rules! dot {
|
||||||
|
() => (TtToken(_, token::Dot))
|
||||||
|
}
|
||||||
macro_rules! eq {
|
macro_rules! eq {
|
||||||
() => (TtToken(_, token::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) {
|
fn splice(&mut self, escape: Escape, sp: Span) {
|
||||||
let tt = match self.input {
|
let mut tts = vec![];
|
||||||
[ref tt, ..] => {
|
// First, munch a single token tree
|
||||||
self.shift(1);
|
if let [ref tt, ..] = self.input {
|
||||||
self.new_rust_parser(vec![tt.clone()]).parse_expr()
|
self.shift(1);
|
||||||
},
|
tts.push(tt.clone());
|
||||||
_ => {
|
}
|
||||||
self.render.cx.span_err(sp, "expected expression for this splice");
|
loop {
|
||||||
return;
|
match self.input {
|
||||||
},
|
// Munch attribute lookups e.g. `$person.address.street`
|
||||||
};
|
[ref dot @ dot!(), ref ident @ ident!(_), ..] => {
|
||||||
self.render.splice(tt, escape);
|
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) {
|
fn element(&mut self, name: &str, sp: Span) {
|
||||||
|
|
|
@ -123,6 +123,33 @@ mod splices {
|
||||||
assert_eq!(s, "Pinkie Pie");
|
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>
|
// FIXME: See <https://github.com/rust-lang/rust/issues/16617>
|
||||||
// for why this is commented out
|
// for why this is commented out
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue