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 #attr_name: Option<#attr_type>, )*
pub data_attributes: std::collections::BTreeMap<String, String>,
#( pub #req_child_name: #req_child_type, )*
#( pub #req_child_name: Box<#req_child_type>, )*
#children
}
)
@ -108,7 +108,7 @@ impl Declare {
quote!(
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 {
#( #attr_name: None, )*
data_attributes: std::collections::BTreeMap::new(),

View File

@ -18,7 +18,9 @@ impl Node {
fn into_token_stream(self) -> TokenStream {
match self {
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"),
}
}
@ -28,21 +30,20 @@ impl Node {
Node::Element(el) => {
let el = el.into_token_stream();
quote!(
element.children.push(Box::new(#el));
element.children.push(#el);
)
}
tx @ Node::Text(_) => {
let tx = tx.into_token_stream();
quote!(
element.children.push(Box::new(#tx));
element.children.push(#tx);
)
}
Node::Block(group) => quote!({
let iter = #group.into_iter();
for child in iter {
element.children.push(Box::new(child));
Node::Block(group) => quote!(
for child in #group.into_iter() {
element.children.push(child);
}
}),
),
}
}
}
@ -119,7 +120,7 @@ impl Element {
#(
#opt_children
)*
element
Box::new(element)
}
)
}

View File

@ -1,10 +1,12 @@
#![feature(proc_macro_hygiene)]
use typed_html::elements::TextNode;
#[macro_use]
extern crate typed_html;
use typed_html_macros::html;
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 doc = html!(
<html>
@ -17,7 +19,7 @@ fn main() {
<p class="mind-blown">{the_big_question}</p>
{
(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>

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);
#[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 {
pub fn new<S: Into<String>>(s: S) -> Self {
TextNode(s.into())