Build a virtual DOM structure.
This commit is contained in:
parent
2806bde178
commit
73344d0dbf
|
@ -0,0 +1,5 @@
|
|||
blacklisted-names = []
|
||||
cyclomatic-complexity-threshold = 100
|
||||
single-char-binding-names-threshold = 15
|
||||
# I HAVE THE POWER OF OLEG
|
||||
type-complexity-threshold = 999999
|
|
@ -96,11 +96,6 @@ impl Declare {
|
|||
|
||||
let mut body = TokenStream::new();
|
||||
|
||||
body.extend(quote!(
|
||||
pub attrs: $attr_type_name,
|
||||
pub data_attributes: std::collections::BTreeMap<String, String>,
|
||||
));
|
||||
|
||||
for (child_name, child_type, _) in self.req_children() {
|
||||
body.extend(quote!( pub $child_name: Box<$child_type>, ));
|
||||
}
|
||||
|
@ -112,6 +107,8 @@ impl Declare {
|
|||
|
||||
quote!(
|
||||
pub struct $elem_name {
|
||||
pub attrs: $attr_type_name,
|
||||
pub data_attributes: std::collections::BTreeMap<String, String>,
|
||||
$body
|
||||
}
|
||||
)
|
||||
|
@ -154,10 +151,58 @@ impl Declare {
|
|||
)
|
||||
}
|
||||
|
||||
fn impl_vnode(&self) -> TokenStream {
|
||||
let elem_name = TokenTree::Literal(Literal::string(self.name.to_string().as_str()));
|
||||
let mut req_children = TokenStream::new();
|
||||
for (child_name, _, _) in self.req_children() {
|
||||
req_children.extend(quote!(
|
||||
children.push(self.$child_name.vnode());
|
||||
));
|
||||
}
|
||||
let mut opt_children = TokenStream::new();
|
||||
if self.opt_children.is_some() {
|
||||
opt_children.extend(quote!(for child in &self.children {
|
||||
children.push(child.vnode());
|
||||
}));
|
||||
}
|
||||
|
||||
let mut push_attrs = TokenStream::new();
|
||||
for (attr_name, _, attr_str) in self.attrs() {
|
||||
push_attrs.extend(quote!(
|
||||
if let Some(ref value) = self.attrs.$attr_name {
|
||||
attributes.push(($attr_str.to_string(), value.to_string()));
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
quote!(
|
||||
let mut attributes = Vec::new();
|
||||
$push_attrs
|
||||
for (key, value) in &self.data_attributes {
|
||||
attributes.push((format!("data-{}", key), value.to_string()));
|
||||
}
|
||||
|
||||
let mut children = Vec::new();
|
||||
$req_children
|
||||
$opt_children
|
||||
|
||||
::elements::VNode::Element(::elements::VElement {
|
||||
name: $elem_name,
|
||||
attributes,
|
||||
children
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
fn impl_node(&self) -> TokenStream {
|
||||
let elem_name = self.elem_name();
|
||||
let vnode = self.impl_vnode();
|
||||
quote!(
|
||||
impl ::elements::Node for $elem_name {}
|
||||
impl ::elements::Node for $elem_name {
|
||||
fn vnode(&self) -> ::elements::VNode {
|
||||
$vnode
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -270,7 +315,7 @@ impl Declare {
|
|||
quote!(
|
||||
impl std::fmt::Display for $elem_name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
write!(f, "<{}", $name);
|
||||
write!(f, "<{}", $name)?;
|
||||
$print_attrs
|
||||
for (key, value) in &self.data_attributes {
|
||||
write!(f, " data-{}={:?}", key, value)?;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
extern crate typed_html;
|
||||
extern crate typed_html_macros;
|
||||
|
||||
use typed_html::elements::Node;
|
||||
use typed_html::types::*;
|
||||
use typed_html_macros::html;
|
||||
|
||||
|
@ -37,4 +38,5 @@ fn main() {
|
|||
</html>
|
||||
);
|
||||
println!("{}", doc.to_string());
|
||||
println!("{:?}", doc.vnode());
|
||||
}
|
||||
|
|
|
@ -6,7 +6,22 @@ use typed_html_macros::declare_element;
|
|||
|
||||
use super::types::*;
|
||||
|
||||
pub trait Node: Display {}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum VNode {
|
||||
Text(String),
|
||||
Element(VElement),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VElement {
|
||||
pub name: &'static str,
|
||||
pub attributes: Vec<(String, String)>,
|
||||
pub children: Vec<VNode>,
|
||||
}
|
||||
|
||||
pub trait Node: Display {
|
||||
fn vnode(&self) -> VNode;
|
||||
}
|
||||
|
||||
pub trait Element: Node {
|
||||
fn name() -> &'static str;
|
||||
|
@ -61,7 +76,11 @@ impl Display for TextNode {
|
|||
}
|
||||
}
|
||||
|
||||
impl Node for TextNode {}
|
||||
impl Node for TextNode {
|
||||
fn vnode(&self) -> VNode {
|
||||
VNode::Text(self.0.clone())
|
||||
}
|
||||
}
|
||||
impl FlowContent for TextNode {}
|
||||
impl PhrasingContent for TextNode {}
|
||||
|
||||
|
|
Loading…
Reference in New Issue