Replace $$
syntax with a general trait thing
This commit is contained in:
parent
48729378cf
commit
2e0aa3e433
4 changed files with 36 additions and 34 deletions
|
@ -8,6 +8,32 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
/// Represents a type that can be rendered as HTML.
|
||||||
|
///
|
||||||
|
/// Most of the time you should implement `std::fmt::Display` instead,
|
||||||
|
/// which will be picked up by the blanket impl.
|
||||||
|
pub trait Render {
|
||||||
|
fn render(&self, &mut fmt::Write) -> fmt::Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: fmt::Display + ?Sized> Render for T {
|
||||||
|
fn render(&self, w: &mut fmt::Write) -> fmt::Result {
|
||||||
|
use std::fmt::Write;
|
||||||
|
write!(Escaper::new(w), "{}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A wrapper that renders the inner value without escaping.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PreEscaped<T>(pub T);
|
||||||
|
|
||||||
|
impl<T: fmt::Display> Render for PreEscaped<T> {
|
||||||
|
fn render(&self, w: &mut fmt::Write) -> fmt::Result {
|
||||||
|
use std::fmt::Write;
|
||||||
|
write!(w, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An adapter that escapes HTML special characters.
|
/// An adapter that escapes HTML special characters.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
|
|
@ -10,7 +10,7 @@ use syntax::parse::token::{BinOpToken, DelimToken, IdentStyle, Token};
|
||||||
use syntax::parse::token::keywords::Keyword;
|
use syntax::parse::token::keywords::Keyword;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
|
||||||
use super::render::{Escape, Renderer};
|
use super::render::Renderer;
|
||||||
|
|
||||||
macro_rules! error {
|
macro_rules! error {
|
||||||
($cx:expr, $sp:expr, $msg:expr) => ({
|
($cx:expr, $sp:expr, $msg:expr) => ({
|
||||||
|
@ -162,15 +162,10 @@ impl<'cx, 'i> Parser<'cx, 'i> {
|
||||||
self.render.emit_call(func);
|
self.render.emit_call(func);
|
||||||
},
|
},
|
||||||
// Splice
|
// Splice
|
||||||
[ref tt @ dollar!(), dollar!(), ..] => {
|
|
||||||
self.shift(2);
|
|
||||||
let expr = try!(self.splice(tt.get_span()));
|
|
||||||
self.render.splice(expr, Escape::PassThru);
|
|
||||||
},
|
|
||||||
[ref tt @ dollar!(), ..] => {
|
[ref tt @ dollar!(), ..] => {
|
||||||
self.shift(1);
|
self.shift(1);
|
||||||
let expr = try!(self.splice(tt.get_span()));
|
let expr = try!(self.splice(tt.get_span()));
|
||||||
self.render.splice(expr, Escape::Escape);
|
self.render.splice(expr);
|
||||||
},
|
},
|
||||||
// Element
|
// Element
|
||||||
[ident!(sp, _), ..] => {
|
[ident!(sp, _), ..] => {
|
||||||
|
@ -205,7 +200,7 @@ impl<'cx, 'i> Parser<'cx, 'i> {
|
||||||
fn literal(&mut self, tt: &TokenTree, minus: bool) -> PResult<()> {
|
fn literal(&mut self, tt: &TokenTree, minus: bool) -> PResult<()> {
|
||||||
let lit = try!(self.with_rust_parser(vec![tt.clone()], RustParser::parse_lit));
|
let lit = try!(self.with_rust_parser(vec![tt.clone()], RustParser::parse_lit));
|
||||||
let s = try!(lit_to_string(self.render.cx, lit, minus));
|
let s = try!(lit_to_string(self.render.cx, lit, minus));
|
||||||
self.render.string(&s, Escape::Escape);
|
self.render.string(&s);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,6 @@ use syntax::ptr::P;
|
||||||
|
|
||||||
use maud::Escaper;
|
use maud::Escaper;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum Escape {
|
|
||||||
PassThru,
|
|
||||||
Escape,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Renderer<'cx> {
|
pub struct Renderer<'cx> {
|
||||||
pub cx: &'cx ExtCtxt<'cx>,
|
pub cx: &'cx ExtCtxt<'cx>,
|
||||||
writer: Ident,
|
writer: Ident,
|
||||||
|
@ -116,29 +110,15 @@ impl<'cx> Renderer<'cx> {
|
||||||
}).unwrap()
|
}).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends a literal string, with the specified escaping method.
|
/// Appends a literal string.
|
||||||
pub fn string(&mut self, s: &str, escape: Escape) {
|
pub fn string(&mut self, s: &str) {
|
||||||
let escaped;
|
self.push_str(&html_escape(s));
|
||||||
let s = match escape {
|
|
||||||
Escape::PassThru => s,
|
|
||||||
Escape::Escape => { escaped = html_escape(s); &*escaped },
|
|
||||||
};
|
|
||||||
self.push_str(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends the result of an expression, with the specified escaping method.
|
/// Appends the result of an expression, with the specified escaping method.
|
||||||
pub fn splice(&mut self, expr: P<Expr>, escape: Escape) {
|
pub fn splice(&mut self, expr: P<Expr>) {
|
||||||
let w = self.writer;
|
let w = self.writer;
|
||||||
let expr = match escape {
|
let expr = quote_expr!(self.cx, ::maud::Render::render(&$expr, &mut *$w));
|
||||||
Escape::PassThru =>
|
|
||||||
quote_expr!(self.cx, write!($w, "{}", $expr)),
|
|
||||||
Escape::Escape =>
|
|
||||||
quote_expr!(self.cx,
|
|
||||||
write!(
|
|
||||||
::maud::Escaper::new(&mut *$w),
|
|
||||||
"{}",
|
|
||||||
$expr)),
|
|
||||||
};
|
|
||||||
let stmt = self.wrap_try(expr);
|
let stmt = self.wrap_try(expr);
|
||||||
self.push(stmt);
|
self.push(stmt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,9 @@ mod splices {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_literals() {
|
fn raw_literals() {
|
||||||
|
use maud::PreEscaped;
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
html!(s, $$"<pinkie>").unwrap();
|
html!(s, $PreEscaped("<pinkie>")).unwrap();
|
||||||
assert_eq!(s, "<pinkie>");
|
assert_eq!(s, "<pinkie>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue