Autobox everything.

This commit is contained in:
Bodil Stokke 2018-10-27 17:28:57 +01:00
parent dee331c5eb
commit f7ce896ca3
4 changed files with 36 additions and 14 deletions

View File

@ -88,7 +88,7 @@ impl Declare {
pub struct #elem_name { pub struct #elem_name {
#( pub #attr_name: Option<#attr_type>, )* #( pub #attr_name: Option<#attr_type>, )*
pub data_attributes: std::collections::BTreeMap<String, String>, pub data_attributes: std::collections::BTreeMap<String, String>,
#( pub #req_child_name: #req_child_type, )* #( pub #req_child_name: Box<#req_child_type>, )*
#children #children
} }
) )
@ -108,7 +108,7 @@ impl Declare {
quote!( quote!(
impl #elem_name { impl #elem_name {
pub fn new(#(#req_child_name: #req_child_type),*) -> Self { pub fn new(#(#req_child_name: Box<#req_child_type>),*) -> Self {
#elem_name { #elem_name {
#( #attr_name: None, )* #( #attr_name: None, )*
data_attributes: std::collections::BTreeMap::new(), data_attributes: std::collections::BTreeMap::new(),

View File

@ -18,7 +18,9 @@ impl Node {
fn into_token_stream(self) -> TokenStream { fn into_token_stream(self) -> TokenStream {
match self { match self {
Node::Element(el) => el.into_token_stream(), Node::Element(el) => el.into_token_stream(),
Node::Text(text) => quote!(typed_html::elements::TextNode::new(#text.to_string())), Node::Text(text) => {
quote!(Box::new(typed_html::elements::TextNode::new(#text.to_string())))
}
Node::Block(_) => panic!("cannot have a block in this position"), Node::Block(_) => panic!("cannot have a block in this position"),
} }
} }
@ -28,21 +30,20 @@ impl Node {
Node::Element(el) => { Node::Element(el) => {
let el = el.into_token_stream(); let el = el.into_token_stream();
quote!( quote!(
element.children.push(Box::new(#el)); element.children.push(#el);
) )
} }
tx @ Node::Text(_) => { tx @ Node::Text(_) => {
let tx = tx.into_token_stream(); let tx = tx.into_token_stream();
quote!( quote!(
element.children.push(Box::new(#tx)); element.children.push(#tx);
) )
} }
Node::Block(group) => quote!({ Node::Block(group) => quote!(
let iter = #group.into_iter(); for child in #group.into_iter() {
for child in iter { element.children.push(child);
element.children.push(Box::new(child));
} }
}), ),
} }
} }
} }
@ -119,7 +120,7 @@ impl Element {
#( #(
#opt_children #opt_children
)* )*
element Box::new(element)
} }
) )
} }

View File

@ -1,10 +1,12 @@
#![feature(proc_macro_hygiene)] #![feature(proc_macro_hygiene)]
use typed_html::elements::TextNode; #[macro_use]
extern crate typed_html;
use typed_html_macros::html; use typed_html_macros::html;
fn main() { fn main() {
let the_big_question = TextNode::new("How does she eat?"); let the_big_question = text!("How does she eat?");
let splain_class = "well-actually"; let splain_class = "well-actually";
let doc = html!( let doc = html!(
<html> <html>
@ -17,7 +19,7 @@ fn main() {
<p class="mind-blown">{the_big_question}</p> <p class="mind-blown">{the_big_question}</p>
{ {
(1..4).map(|i| { (1..4).map(|i| {
html!(<p>{ TextNode::new(format!("{}. Ceci n'est pas une chatte.", i)) }</p>) html!(<p>{ text!("{}. Ceci n'est pas une chatte.", i) }</p>)
}) })
} }
</body> </body>

View File

@ -28,8 +28,27 @@ impl IntoIterator for TextNode {
} }
} }
impl IntoIterator for Box<TextNode> {
type Item = Box<TextNode>;
type IntoIter = std::vec::IntoIter<Box<TextNode>>;
fn into_iter(self) -> Self::IntoIter {
vec![self].into_iter()
}
}
pub struct TextNode(String); pub struct TextNode(String);
#[macro_export]
macro_rules! text {
($t:expr) => {
Box::new($crate::elements::TextNode::new($t))
};
($format:tt, $($tail:tt),*) => {
Box::new($crate::elements::TextNode::new(format!($format, $($tail),*)))
};
}
impl TextNode { impl TextNode {
pub fn new<S: Into<String>>(s: S) -> Self { pub fn new<S: Into<String>>(s: S) -> Self {
TextNode(s.into()) TextNode(s.into())