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();
|
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() {
|
for (child_name, child_type, _) in self.req_children() {
|
||||||
body.extend(quote!( pub $child_name: Box<$child_type>, ));
|
body.extend(quote!( pub $child_name: Box<$child_type>, ));
|
||||||
}
|
}
|
||||||
|
@ -112,6 +107,8 @@ impl Declare {
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
pub struct $elem_name {
|
pub struct $elem_name {
|
||||||
|
pub attrs: $attr_type_name,
|
||||||
|
pub data_attributes: std::collections::BTreeMap<String, String>,
|
||||||
$body
|
$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 {
|
fn impl_node(&self) -> TokenStream {
|
||||||
let elem_name = self.elem_name();
|
let elem_name = self.elem_name();
|
||||||
|
let vnode = self.impl_vnode();
|
||||||
quote!(
|
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!(
|
quote!(
|
||||||
impl std::fmt::Display for $elem_name {
|
impl std::fmt::Display for $elem_name {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||||
write!(f, "<{}", $name);
|
write!(f, "<{}", $name)?;
|
||||||
$print_attrs
|
$print_attrs
|
||||||
for (key, value) in &self.data_attributes {
|
for (key, value) in &self.data_attributes {
|
||||||
write!(f, " data-{}={:?}", key, value)?;
|
write!(f, " data-{}={:?}", key, value)?;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
extern crate typed_html;
|
extern crate typed_html;
|
||||||
extern crate typed_html_macros;
|
extern crate typed_html_macros;
|
||||||
|
|
||||||
|
use typed_html::elements::Node;
|
||||||
use typed_html::types::*;
|
use typed_html::types::*;
|
||||||
use typed_html_macros::html;
|
use typed_html_macros::html;
|
||||||
|
|
||||||
|
@ -37,4 +38,5 @@ fn main() {
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
println!("{}", doc.to_string());
|
println!("{}", doc.to_string());
|
||||||
|
println!("{:?}", doc.vnode());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,22 @@ use typed_html_macros::declare_element;
|
||||||
|
|
||||||
use super::types::*;
|
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 {
|
pub trait Element: Node {
|
||||||
fn name() -> &'static str;
|
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 FlowContent for TextNode {}
|
||||||
impl PhrasingContent for TextNode {}
|
impl PhrasingContent for TextNode {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue