1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
#![feature(proc_macro_diagnostic)] extern crate proc_macro; mod child; mod children; mod element; mod element_attribute; mod element_attributes; mod tags; use element::Element; use proc_macro::TokenStream; use quote::quote; use syn::parse_macro_input; /// Render a component tree to an HTML string, using XML-like tags. /// /// The ergonomics are based on JSX: /// /// ### Simple HTML elements start with a lowercase /// /// ```rust /// # #![feature(proc_macro_hygiene)] /// # use pretty_assertions::assert_eq; /// # use render_macros::html; /// let rendered = html! { <div id={"main"}>{"Hello"}</div> }; /// assert_eq!(rendered, r#"<div id="main">Hello</div>"#); /// ``` /// /// ### Custom components start with an uppercase /// /// ```rust /// # #![feature(proc_macro_hygiene)] /// # use pretty_assertions::assert_eq; /// # use render_macros::html; /// use render::Renderable; /// /// #[derive(Debug)] /// struct Heading<'t> { title: &'t str } /// /// impl<'t> Renderable for Heading<'t> { /// fn render(self) -> String { /// html! { <h1>{self.title}</h1> } /// } /// } /// /// let rendered = html! { <Heading title={"Hello world!"} /> }; /// /// assert_eq!(rendered, r#"<h1>Hello world!</h1>"#); /// ``` /// /// ### Punning is supported /// but instead of expanding to `value={true}`, it expands to /// `value={value}` like Rust's punning /// /// ```rust /// # #![feature(proc_macro_hygiene)] /// # use render_macros::html; /// # use pretty_assertions::assert_eq; /// let class = "some_class"; /// /// let rendered = html! { /// <div class /> /// }; /// /// assert_eq!(rendered, r#"<div class="some_class" />"#); /// ``` /// /// ### Values are always surrounded by curly braces /// /// ```rust /// # #![feature(proc_macro_hygiene)] /// # use render_macros::html; /// # use pretty_assertions::assert_eq; /// let rendered = html! { /// <div id={"main"} /> /// }; /// /// assert_eq!(rendered, r#"<div id="main" />"#); /// ``` #[proc_macro] pub fn html(input: TokenStream) -> TokenStream { let el = proc_macro2::TokenStream::from(rsx(input)); let result = quote! { ::render::Renderable::render(#el) }; TokenStream::from(result) } /// Generate a renderable component tree, before rendering it #[proc_macro] pub fn rsx(input: TokenStream) -> TokenStream { let el = parse_macro_input!(input as Element); let result = quote! { #el }; TokenStream::from(result) }