maud_macros 0.5.1

Compile-time HTML templates.
#![crate_type = "dylib"]
#![feature(plugin_registrar, quote)]
#![feature(slice_patterns)]
#![feature(rustc_private)]

extern crate syntax;
extern crate rustc;
extern crate maud;

use syntax::ast::{Expr, TokenTree, TtToken};
use syntax::codemap::{DUMMY_SP, Span};
use syntax::ext::base::{ExtCtxt, MacEager, MacResult};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
use rustc::plugin::Registry;

mod parse;
mod render;

fn _expand_html(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> P<Expr> {
    let (write, input) = parse::split_comma(cx, sp, args);
    parse::parse(cx, sp, write, input)
}

fn _expand_write_html(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> P<Expr> {
    let (io_write, input) = parse::split_comma(cx, sp, args);
    let io_write = io_write.to_vec();
    let fmt_write = token::gensym_ident("__maud_utf8_writer");
    let fmt_write = vec![
        TtToken(DUMMY_SP, token::Ident(fmt_write, token::IdentStyle::Plain))];
    let expr = parse::parse(cx, sp, &fmt_write, input);
    quote_expr!(cx,
        match ::maud::Utf8Writer::new(&mut $io_write) {
            mut $fmt_write => {
                let _ = $expr;
                $fmt_write.into_result()
            }
        })
}

macro_rules! expand {
    ($name:ident $debug_name:ident $inner_fn:ident) => {
        fn $name<'cx>(cx: &'cx mut ExtCtxt, sp: Span, args: &[TokenTree])
            -> Box<MacResult + 'cx>
        {
            let expr = $inner_fn(cx, sp, args);
            MacEager::expr(expr)
        }

        fn $debug_name<'cx>(cx: &'cx mut ExtCtxt, sp: Span, args: &[TokenTree])
            -> Box<MacResult + 'cx>
        {
            let expr = $inner_fn(cx, sp, args);
            cx.span_note(sp, &format!("expansion:\n{}",
                                      pprust::expr_to_string(&expr)));
            MacEager::expr(expr)
        }
    }
}

expand!(expand_html expand_html_debug _expand_html);
expand!(expand_write_html expand_write_html_debug _expand_write_html);

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("html", expand_html);
    reg.register_macro("html_debug", expand_html_debug);
    reg.register_macro("write_html", expand_write_html);
    reg.register_macro("write_html_debug", expand_write_html_debug);
}