maud/maud_macros/src/lib.rs

81 lines
2.7 KiB
Rust
Raw Normal View History

2014-12-17 21:11:56 +13:00
#![crate_type = "dylib"]
#![feature(plugin_registrar, quote)]
2015-03-29 19:37:26 +13:00
#![feature(slice_patterns)]
#![feature(rustc_private)]
2014-12-17 21:11:56 +13:00
2015-11-28 21:15:13 +11:00
extern crate rustc_plugin;
2014-12-17 21:11:56 +13:00
extern crate syntax;
2014-12-19 11:53:40 +13:00
extern crate maud;
2014-12-17 21:11:56 +13:00
2015-11-28 21:15:13 +11:00
use rustc_plugin::Registry;
2015-11-08 18:59:11 +13:00
use syntax::ast::{Expr, TokenTree};
use syntax::codemap::{DUMMY_SP, Span};
2016-01-01 11:43:59 +13:00
use syntax::errors::FatalError;
2015-09-15 13:26:13 +12:00
use syntax::ext::base::{DummyResult, ExtCtxt, MacEager, MacResult};
2016-01-01 11:43:59 +13:00
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
2014-12-17 21:11:56 +13:00
2014-12-18 18:57:55 +13:00
mod parse;
mod render;
2014-12-17 21:11:56 +13:00
2016-01-01 11:43:59 +13:00
pub type PResult<T> = Result<T, FatalError>;
2015-09-15 13:26:13 +12:00
fn html(cx: &mut ExtCtxt, sp: Span, mac_name: &str, args: &[TokenTree]) -> PResult<P<Expr>> {
let (write, input) = try!(parse::split_comma(cx, sp, mac_name, args));
parse::parse(cx, sp, write, input)
2014-12-17 21:11:56 +13:00
}
2015-09-15 13:26:13 +12:00
fn html_utf8(cx: &mut ExtCtxt, sp: Span, mac_name: &str, args: &[TokenTree]) -> PResult<P<Expr>> {
let (io_write, input) = try!(parse::split_comma(cx, sp, mac_name, args));
let io_write = io_write.to_vec();
let fmt_write = token::gensym_ident("__maud_utf8_writer");
let fmt_write = vec![
2015-11-08 18:59:11 +13:00
TokenTree::Token(DUMMY_SP, token::Ident(fmt_write, token::IdentStyle::Plain))];
2015-09-15 13:26:13 +12:00
let expr = try!(parse::parse(cx, sp, &fmt_write, input));
Ok(quote_expr!(cx,
match ::maud::Utf8Writer::new(&mut $io_write) {
mut $fmt_write => {
let _ = $expr;
$fmt_write.into_result()
}
2015-09-15 13:26:13 +12:00
}))
}
macro_rules! generate_debug_wrappers {
2015-09-15 13:26:13 +12:00
($fn_name:ident $fn_debug_name:ident $mac_name:ident) => {
fn $fn_name<'cx>(cx: &'cx mut ExtCtxt, sp: Span, args: &[TokenTree])
-> Box<MacResult + 'cx>
{
2015-09-15 13:26:13 +12:00
match $mac_name(cx, sp, stringify!($mac_name), args) {
Ok(expr) => MacEager::expr(expr),
Err(..) => DummyResult::expr(sp),
}
}
2015-09-15 13:26:13 +12:00
fn $fn_debug_name<'cx>(cx: &'cx mut ExtCtxt, sp: Span, args: &[TokenTree])
-> Box<MacResult + 'cx>
{
2015-09-15 13:26:13 +12:00
match $mac_name(cx, sp, concat!(stringify!($mac_name), "_debug"), args) {
Ok(expr) => {
2016-01-01 11:43:59 +13:00
cx.span_warn(sp, &format!("expansion:\n{}",
2015-09-15 13:26:13 +12:00
pprust::expr_to_string(&expr)));
MacEager::expr(expr)
},
Err(..) => DummyResult::expr(sp),
}
}
}
}
2015-09-15 13:26:13 +12:00
generate_debug_wrappers!(expand_html expand_html_debug html);
generate_debug_wrappers!(expand_html_utf8 expand_html_utf8_debug html_utf8);
2014-12-17 21:11:56 +13:00
#[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("html_utf8", expand_html_utf8);
reg.register_macro("html_utf8_debug", expand_html_utf8_debug);
2014-12-17 21:11:56 +13:00
}