// use proc_macro2::TokenStream; // use quote::TokenStreamExt; // use quote::{quote, ToTokens}; // use syn::{Expr, Ident, LitStr}; // #[cfg(any(feature = "hot-reload", debug_assertions))] // pub fn try_parse_template( // rsx: &str, // location: OwnedCodeLocation, // previous_template: Option, // ) -> Result<(OwnedTemplate, DynamicTemplateContextBuilder), Error> { // use crate::CallBody; // let call_body: CallBody = // syn::parse_str(rsx).map_err(|e| Error::ParseError(ParseError::new(e, location.clone())))?; // let mut template_builder = TemplateBuilder::from_roots_always(call_body.roots); // if let Some(prev) = previous_template { // template_builder = template_builder // .try_switch_dynamic_context(prev) // .ok_or_else(|| { // Error::RecompileRequiredError(RecompileReason::Variable( // "dynamic context updated".to_string(), // )) // })?; // } // let dyn_ctx = template_builder.dynamic_context.clone(); // Ok((template_builder.try_into_owned(&location)?, dyn_ctx)) // } // use crate::{BodyNode, ElementAttr, FormattedSegment, Segment}; // struct TemplateElementBuilder { // tag: Ident, // attributes: Vec, // children: Vec, // listeners: Vec, // locally_static: bool, // } // #[cfg(any(feature = "hot-reload", debug_assertions))] // type OwndedTemplateElement = TemplateElement< // Vec>, // OwnedAttributeValue, // Vec, // Vec, // >; // impl TemplateElementBuilder { // #[cfg(any(feature = "hot-reload", debug_assertions))] // fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { // let Self { // tag, // attributes, // children, // listeners, // .. // } = self; // let (element_tag, element_ns) = // element_to_static_str(&tag.to_string()).ok_or_else(|| { // Error::ParseError(ParseError::new( // syn::Error::new(tag.span(), format!("unknown element: {}", tag)), // location.clone(), // )) // })?; // let mut owned_attributes = Vec::new(); // for a in attributes { // owned_attributes.push(a.try_into_owned(location, element_tag, element_ns)?); // } // Ok(TemplateElement::new( // element_tag, // element_ns, // owned_attributes, // children, // listeners, // )) // } // } // impl ToTokens for TemplateElementBuilder { // fn to_tokens(&self, tokens: &mut TokenStream) { // let Self { // tag, // attributes, // children, // listeners, // .. // } = self; // let children = children.iter().map(|id| { // let raw = id.0; // quote! {TemplateNodeId(#raw)} // }); // tokens.append_all(quote! { // TemplateElement::new( // dioxus_elements::#tag::TAG_NAME, // dioxus_elements::#tag::NAME_SPACE, // &[#(#attributes),*], // &[#(#children),*], // &[#(#listeners),*], // ) // }) // } // } // enum AttributeName { // Ident(Ident), // Str(LitStr), // } // struct TemplateAttributeBuilder { // element_tag: Ident, // name: AttributeName, // value: TemplateAttributeValue, // } // impl TemplateAttributeBuilder { // #[cfg(any(feature = "hot-reload", debug_assertions))] // fn try_into_owned( // self, // location: &OwnedCodeLocation, // element_tag: &'static str, // element_ns: Option<&'static str>, // ) -> Result, Error> { // let Self { name, value, .. } = self; // let (name, span, literal) = match name { // AttributeName::Ident(name) => (name.to_string(), name.span(), false), // AttributeName::Str(name) => (name.value(), name.span(), true), // }; // let (name, namespace, volatile) = attrbute_to_static_str(&name, element_tag, element_ns) // .ok_or_else(|| { // if literal { // // literals will be captured when a full recompile is triggered // Error::RecompileRequiredError(RecompileReason::Attribute(name.to_string())) // } else { // Error::ParseError(ParseError::new( // syn::Error::new(span, format!("unknown attribute: {}", name)), // location.clone(), // )) // } // })?; // let attribute = AttributeDiscription { // name, // namespace, // volatile, // }; // Ok(TemplateAttribute { value, attribute }) // } // } // impl ToTokens for TemplateAttributeBuilder { // fn to_tokens(&self, tokens: &mut TokenStream) { // let Self { // element_tag, // name, // value, // } = self; // let value = match value { // TemplateAttributeValue::Static(val) => { // let val = match val { // OwnedAttributeValue::Text(txt) => quote! {StaticAttributeValue::Text(#txt)}, // OwnedAttributeValue::Float32(f) => quote! {StaticAttributeValue::Float32(#f)}, // OwnedAttributeValue::Float64(f) => quote! {StaticAttributeValue::Float64(#f)}, // OwnedAttributeValue::Int32(i) => quote! {StaticAttributeValue::Int32(#i)}, // OwnedAttributeValue::Int64(i) => quote! {StaticAttributeValue::Int64(#i)}, // OwnedAttributeValue::Uint32(u) => quote! {StaticAttributeValue::Uint32(#u)}, // OwnedAttributeValue::Uint64(u) => quote! {StaticAttributeValue::Uint64(#u)}, // OwnedAttributeValue::Bool(b) => quote! {StaticAttributeValue::Bool(#b)}, // OwnedAttributeValue::Vec3Float(f1, f2, f3) => { // quote! {StaticAttributeValue::Vec3Float(#f1, #f2, #f3)} // } // OwnedAttributeValue::Vec3Int(f1, f2, f3) => { // quote! {StaticAttributeValue::Vec3Int(#f1, #f2, #f3)} // } // OwnedAttributeValue::Vec3Uint(f1, f2, f3) => { // quote! {StaticAttributeValue::Vec3Uint(#f1, #f2, #f3)} // } // OwnedAttributeValue::Vec4Float(f1, f2, f3, f4) => { // quote! {StaticAttributeValue::Vec4Float(#f1, #f2, #f3, #f4)} // } // OwnedAttributeValue::Vec4Int(f1, f2, f3, f4) => { // quote! {StaticAttributeValue::Vec4Int(#f1, #f2, #f3, #f4)} // } // OwnedAttributeValue::Vec4Uint(f1, f2, f3, f4) => { // quote! {StaticAttributeValue::Vec4Uint(#f1, #f2, #f3, #f4)} // } // OwnedAttributeValue::Bytes(b) => { // quote! {StaticAttributeValue::Bytes(&[#(#b),*])} // } // OwnedAttributeValue::Any(_) => todo!(), // }; // quote! {TemplateAttributeValue::Static(#val)} // } // TemplateAttributeValue::Dynamic(idx) => quote! {TemplateAttributeValue::Dynamic(#idx)}, // }; // match name { // AttributeName::Ident(name) => tokens.append_all(quote! { // TemplateAttribute{ // attribute: dioxus_elements::#element_tag::#name, // value: #value, // } // }), // AttributeName::Str(lit) => tokens.append_all(quote! { // TemplateAttribute{ // attribute: dioxus::prelude::AttributeDiscription{ // name: #lit, // namespace: None, // volatile: false // }, // value: #value, // } // }), // } // } // } // enum TemplateNodeTypeBuilder { // Element(TemplateElementBuilder), // Text(TextTemplate>, String>), // DynamicNode(usize), // } // #[cfg(any(feature = "hot-reload", debug_assertions))] // type OwnedTemplateNodeType = TemplateNodeType< // Vec>, // OwnedAttributeValue, // Vec, // Vec, // Vec>, // String, // >; // impl TemplateNodeTypeBuilder { // #[cfg(any(feature = "hot-reload", debug_assertions))] // fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { // match self { // TemplateNodeTypeBuilder::Element(el) => { // Ok(TemplateNodeType::Element(el.try_into_owned(location)?)) // } // TemplateNodeTypeBuilder::Text(txt) => Ok(TemplateNodeType::Text(txt)), // TemplateNodeTypeBuilder::DynamicNode(idx) => Ok(TemplateNodeType::DynamicNode(idx)), // } // } // } // impl ToTokens for TemplateNodeTypeBuilder { // fn to_tokens(&self, tokens: &mut TokenStream) { // match self { // TemplateNodeTypeBuilder::Element(el) => tokens.append_all(quote! { // TemplateNodeType::Element(#el) // }), // TemplateNodeTypeBuilder::Text(txt) => { // let mut length = 0; // let segments = txt.segments.iter().map(|seg| match seg { // TextTemplateSegment::Static(s) => { // length += s.len(); // quote!(TextTemplateSegment::Static(#s)) // } // TextTemplateSegment::Dynamic(idx) => quote!(TextTemplateSegment::Dynamic(#idx)), // }); // tokens.append_all(quote! { // TemplateNodeType::Text(TextTemplate::new(&[#(#segments),*], #length)) // }); // } // TemplateNodeTypeBuilder::DynamicNode(idx) => tokens.append_all(quote! { // TemplateNodeType::DynamicNode(#idx) // }), // } // } // } // struct TemplateNodeBuilder { // id: TemplateNodeId, // depth: usize, // parent: Option, // node_type: TemplateNodeTypeBuilder, // fully_static: bool, // } // impl TemplateNodeBuilder { // #[cfg(any(feature = "hot-reload", debug_assertions))] // fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { // let TemplateNodeBuilder { // id, // node_type, // parent, // depth, // .. // } = self; // let node_type = node_type.try_into_owned(location)?; // Ok(OwnedTemplateNode { // id, // node_type, // parent, // depth, // }) // } // fn to_tokens(&self, tokens: &mut TokenStream) { // let Self { // id, // node_type, // parent, // depth, // .. // } = self; // let raw_id = id.0; // let parent = match parent { // Some(id) => { // let id = id.0; // quote! {Some(TemplateNodeId(#id))} // } // None => quote! {None}, // }; // tokens.append_all(quote! { // TemplateNode { // id: TemplateNodeId(#raw_id), // node_type: #node_type, // parent: #parent, // depth: #depth, // } // }) // } // } // #[derive(Default)] // pub struct TemplateBuilder { // nodes: Vec, // root_nodes: Vec, // dynamic_context: DynamicTemplateContextBuilder, // } // impl TemplateBuilder { // /// Create a template builder from nodes if it would improve performance to do so. // pub fn from_roots(roots: Vec) -> Option { // let mut builder = Self::default(); // for (i, root) in roots.into_iter().enumerate() { // let id = builder.build_node(root, None, vec![i], 0); // builder.root_nodes.push(id); // } // // only build a template if there is at least one static node // if builder // .nodes // .iter() // .all(|r| matches!(&r.node_type, TemplateNodeTypeBuilder::DynamicNode(_))) // { // None // } else { // Some(builder) // } // } // /// Create a template builder from nodes regardless of performance. // #[cfg(any(feature = "hot-reload", debug_assertions))] // fn from_roots_always(roots: Vec) -> Self { // let mut builder = Self::default(); // for (i, root) in roots.into_iter().enumerate() { // let id = builder.build_node(root, None, vec![i], 0); // builder.root_nodes.push(id); // } // builder // } // fn build_node( // &mut self, // node: BodyNode, // parent: Option, // path: Vec, // depth: usize, // ) -> TemplateNodeId { // let id = TemplateNodeId(self.nodes.len()); // match node { // BodyNode::Element(el) => { // let mut locally_static = true; // let mut attributes = Vec::new(); // let mut listeners = Vec::new(); // for attr in el.attributes { // match attr.attr { // ElementAttr::AttrText { name, value } => { // if let Some(static_value) = value.to_static() { // attributes.push(TemplateAttributeBuilder { // element_tag: el.name.clone(), // name: AttributeName::Ident(name), // value: TemplateAttributeValue::Static( // OwnedAttributeValue::Text(static_value), // ), // }) // } else { // locally_static = false; // attributes.push(TemplateAttributeBuilder { // element_tag: el.name.clone(), // name: AttributeName::Ident(name), // value: TemplateAttributeValue::Dynamic( // self.dynamic_context.add_attr(quote!(#value)), // ), // }) // } // } // ElementAttr::CustomAttrText { name, value } => { // if let Some(static_value) = value.to_static() { // attributes.push(TemplateAttributeBuilder { // element_tag: el.name.clone(), // name: AttributeName::Str(name), // value: TemplateAttributeValue::Static( // OwnedAttributeValue::Text(static_value), // ), // }) // } else { // locally_static = false; // attributes.push(TemplateAttributeBuilder { // element_tag: el.name.clone(), // name: AttributeName::Str(name), // value: TemplateAttributeValue::Dynamic( // self.dynamic_context.add_attr(quote!(#value)), // ), // }) // } // } // ElementAttr::AttrExpression { name, value } => { // locally_static = false; // attributes.push(TemplateAttributeBuilder { // element_tag: el.name.clone(), // name: AttributeName::Ident(name), // value: TemplateAttributeValue::Dynamic( // self.dynamic_context.add_attr(quote!(#value)), // ), // }) // } // ElementAttr::CustomAttrExpression { name, value } => { // locally_static = false; // attributes.push(TemplateAttributeBuilder { // element_tag: el.name.clone(), // name: AttributeName::Str(name), // value: TemplateAttributeValue::Dynamic( // self.dynamic_context.add_attr(quote!(#value)), // ), // }) // } // ElementAttr::EventTokens { name, tokens } => { // locally_static = false; // listeners.push(self.dynamic_context.add_listener(name, tokens)) // } // } // } // if let Some(key) = el.key { // self.dynamic_context.add_key(quote!( // dioxus::core::exports::bumpalo::format!(in __bump, "{}", #key) // .into_bump_str() // )); // } // self.nodes.push(TemplateNodeBuilder { // id, // node_type: TemplateNodeTypeBuilder::Element(TemplateElementBuilder { // tag: el.name, // attributes, // children: Vec::new(), // listeners, // locally_static, // }), // parent, // depth, // fully_static: false, // }); // let children: Vec<_> = el // .children // .into_iter() // .enumerate() // .map(|(i, child)| { // let mut new_path = path.clone(); // new_path.push(i); // self.build_node(child, Some(id), new_path, depth + 1) // }) // .collect(); // let children_fully_static = children.iter().all(|c| self.nodes[c.0].fully_static); // let parent = &mut self.nodes[id.0]; // parent.fully_static = locally_static && children_fully_static; // if let TemplateNodeTypeBuilder::Element(element) = &mut parent.node_type { // element.children = children; // } // } // BodyNode::Component(comp) => { // self.nodes.push(TemplateNodeBuilder { // id, // node_type: TemplateNodeTypeBuilder::DynamicNode( // self.dynamic_context.add_node(BodyNode::Component(comp)), // ), // parent, // depth, // fully_static: false, // }); // } // BodyNode::Text(txt) => { // let mut segments = Vec::new(); // let mut length = 0; // let mut fully_static = true; // for segment in txt.segments { // segments.push(match segment { // Segment::Literal(lit) => { // length += lit.len(); // TextTemplateSegment::Static(lit) // } // Segment::Formatted(fmted) => { // fully_static = false; // TextTemplateSegment::Dynamic(self.dynamic_context.add_text(fmted)) // } // }) // } // self.nodes.push(TemplateNodeBuilder { // id, // node_type: TemplateNodeTypeBuilder::Text(TextTemplate::new(segments, length)), // parent, // depth, // fully_static, // }); // } // BodyNode::RawExpr(expr) => { // self.nodes.push(TemplateNodeBuilder { // id, // node_type: TemplateNodeTypeBuilder::DynamicNode( // self.dynamic_context.add_node(BodyNode::RawExpr(expr)), // ), // parent, // depth, // fully_static: false, // }); // } // } // id // } // #[cfg(any(feature = "hot-reload", debug_assertions))] // pub fn try_switch_dynamic_context( // mut self, // dynamic_context: DynamicTemplateContextBuilder, // ) -> Option { // let attribute_mapping: HashMap = dynamic_context // .attributes // .iter() // .enumerate() // .map(|(i, ts)| (ts.to_string(), i)) // .collect(); // let text_mapping: HashMap = dynamic_context // .text // .iter() // .enumerate() // .map(|(i, ts)| (ts.to_token_stream().to_string(), i)) // .collect(); // let listener_mapping: HashMap<(String, Expr), usize> = dynamic_context // .listeners // .iter() // .enumerate() // .map(|(i, ts)| (ts.clone(), i)) // .collect(); // let node_mapping: HashMap = dynamic_context // .nodes // .iter() // .enumerate() // .map(|(i, ts)| (ts.to_token_stream().to_string(), i)) // .collect(); // for node in &mut self.nodes { // match &mut node.node_type { // TemplateNodeTypeBuilder::Element(element) => { // for listener in &mut element.listeners { // *listener = // *listener_mapping.get(&self.dynamic_context.listeners[*listener])?; // } // for attribute in &mut element.attributes { // if let TemplateAttributeValue::Dynamic(idx) = &mut attribute.value { // *idx = *attribute_mapping // .get(&self.dynamic_context.attributes[*idx].to_string())?; // } // } // } // TemplateNodeTypeBuilder::Text(txt) => { // for seg in &mut txt.segments { // if let TextTemplateSegment::Dynamic(idx) = seg { // *idx = *text_mapping.get( // &self.dynamic_context.text[*idx] // .to_token_stream() // .to_string(), // )?; // } // } // } // TemplateNodeTypeBuilder::DynamicNode(idx) => { // *idx = *node_mapping.get( // &self.dynamic_context.nodes[*idx] // .to_token_stream() // .to_string(), // )?; // } // } // } // self.dynamic_context = dynamic_context; // Some(self) // } // #[cfg(any(feature = "hot-reload", debug_assertions))] // pub fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { // let mut nodes = Vec::new(); // let dynamic_mapping = self.dynamic_mapping(&nodes); // let dynamic_path = self.dynamic_path(); // for node in self.nodes { // nodes.push(node.try_into_owned(location)?); // } // Ok(OwnedTemplate { // nodes, // root_nodes: self.root_nodes, // dynamic_mapping, // dynamic_path, // }) // } // #[cfg(any(feature = "hot-reload", debug_assertions))] // pub fn dynamic_mapping( // &self, // resolved_nodes: &Vec, // ) -> OwnedDynamicNodeMapping { // let dynamic_context = &self.dynamic_context; // let mut node_mapping = vec![None; dynamic_context.nodes.len()]; // let nodes = &self.nodes; // for n in nodes { // if let TemplateNodeTypeBuilder::DynamicNode(idx) = &n.node_type { // node_mapping[*idx] = Some(n.id) // } // } // let mut text_mapping = vec![Vec::new(); dynamic_context.text.len()]; // for n in nodes { // if let TemplateNodeTypeBuilder::Text(txt) = &n.node_type { // for seg in &txt.segments { // match seg { // TextTemplateSegment::Static(_) => (), // TextTemplateSegment::Dynamic(idx) => text_mapping[*idx].push(n.id), // } // } // } // } // let mut attribute_mapping = vec![Vec::new(); dynamic_context.attributes.len()]; // for n in nodes { // if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { // for (i, attr) in el.attributes.iter().enumerate() { // match attr.value { // TemplateAttributeValue::Static(_) => (), // TemplateAttributeValue::Dynamic(idx) => { // attribute_mapping[idx].push((n.id, i)); // } // } // } // } // } // let mut listener_mapping = Vec::new(); // for n in nodes { // if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { // if !el.listeners.is_empty() { // listener_mapping.push(n.id); // } // } // } // let mut volatile_mapping = Vec::new(); // for n in resolved_nodes { // if let TemplateNodeType::Element(el) = &n.node_type { // for (i, attr) in el.attributes.iter().enumerate() { // if attr.attribute.volatile { // volatile_mapping.push((n.id, i)); // } // } // } // } // OwnedDynamicNodeMapping::new( // node_mapping, // text_mapping, // attribute_mapping, // volatile_mapping, // listener_mapping, // ) // } // fn dynamic_path(&self) -> Option { // let mut last_seg: Option = None; // let mut nodes_to_insert_after = Vec::new(); // // iterating from the last root to the first // for root in self.root_nodes.iter().rev() { // let root_node = &self.nodes[root.0]; // if let TemplateNodeTypeBuilder::DynamicNode(_) = root_node.node_type { // match &mut last_seg { // // if there has been no static nodes, we can append the child to the parent node // None => nodes_to_insert_after.push(*root), // // otherwise we insert the child before the last static node // Some(seg) => { // seg.ops.push(UpdateOp::InsertBefore(*root)); // } // } // } else if let Some(mut new) = self.construct_path_segment(*root) { // if let Some(last) = last_seg.take() { // match new.traverse { // OwnedTraverse::Halt => { // new.traverse = OwnedTraverse::NextSibling(Box::new(last)); // } // OwnedTraverse::FirstChild(b) => { // new.traverse = OwnedTraverse::Both(Box::new((*b, last))); // } // _ => unreachable!(), // } // } else { // for node in nodes_to_insert_after.drain(..) { // new.ops.push(UpdateOp::InsertAfter(node)); // } // } // last_seg = Some(new); // } else if let Some(last) = last_seg.take() { // last_seg = Some(OwnedPathSeg { // ops: Vec::new(), // traverse: OwnedTraverse::NextSibling(Box::new(last)), // }); // } // } // last_seg // } // fn construct_path_segment(&self, node_id: TemplateNodeId) -> Option { // let n = &self.nodes[node_id.0]; // if n.fully_static { // return None; // } // match &n.node_type { // TemplateNodeTypeBuilder::Element(el) => { // let mut last_seg: Option = None; // let mut children_to_append = Vec::new(); // // iterating from the last child to the first // for child in el.children.iter().rev() { // let child_node = &self.nodes[child.0]; // if let TemplateNodeTypeBuilder::DynamicNode(_) = child_node.node_type { // match &mut last_seg { // // if there has been no static nodes, we can append the child to the parent node // None => children_to_append.push(*child), // // otherwise we insert the child before the last static node // Some(seg) => { // seg.ops.push(UpdateOp::InsertBefore(*child)); // } // } // } else if let Some(mut new) = self.construct_path_segment(*child) { // if let Some(last) = last_seg.take() { // match new.traverse { // OwnedTraverse::Halt => { // new.traverse = OwnedTraverse::NextSibling(Box::new(last)); // } // OwnedTraverse::FirstChild(b) => { // new.traverse = OwnedTraverse::Both(Box::new((*b, last))); // } // _ => unreachable!(), // } // } // last_seg = Some(new); // } else if let Some(last) = last_seg.take() { // last_seg = Some(OwnedPathSeg { // ops: Vec::new(), // traverse: OwnedTraverse::NextSibling(Box::new(last)), // }); // } // } // let mut ops = Vec::new(); // if !el.locally_static || n.parent.is_none() { // ops.push(UpdateOp::StoreNode(node_id)); // } // for child in children_to_append.into_iter().rev() { // ops.push(UpdateOp::AppendChild(child)); // } // Some(OwnedPathSeg { // ops, // traverse: match last_seg { // Some(last) => OwnedTraverse::FirstChild(Box::new(last)), // None => OwnedTraverse::Halt, // }, // }) // } // TemplateNodeTypeBuilder::Text(_) => Some(OwnedPathSeg { // ops: vec![UpdateOp::StoreNode(n.id)], // traverse: dioxus_core::OwnedTraverse::Halt, // }), // TemplateNodeTypeBuilder::DynamicNode(_) => unreachable!( // "constructing path segment for dynamic nodes is handled in the parent node" // ), // } // } // } // impl ToTokens for TemplateBuilder { // fn to_tokens(&self, tokens: &mut TokenStream) { // let Self { // nodes, // root_nodes, // dynamic_context, // } = self; // let mut node_mapping = vec![None; dynamic_context.nodes.len()]; // for n in nodes { // if let TemplateNodeTypeBuilder::DynamicNode(idx) = &n.node_type { // node_mapping[*idx] = Some(n.id); // } // } // let mut text_mapping = vec![Vec::new(); dynamic_context.text.len()]; // for n in nodes { // if let TemplateNodeTypeBuilder::Text(txt) = &n.node_type { // for seg in &txt.segments { // match seg { // TextTemplateSegment::Static(_) => (), // TextTemplateSegment::Dynamic(idx) => text_mapping[*idx].push(n.id), // } // } // } // } // let mut attribute_mapping = vec![Vec::new(); dynamic_context.attributes.len()]; // for n in nodes { // if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { // for (i, attr) in el.attributes.iter().enumerate() { // match attr.value { // TemplateAttributeValue::Static(_) => (), // TemplateAttributeValue::Dynamic(idx) => { // attribute_mapping[idx].push((n.id, i)); // } // } // } // } // } // let mut listener_mapping = Vec::new(); // for n in nodes { // if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { // if !el.listeners.is_empty() { // listener_mapping.push(n.id); // } // } // } // let root_nodes = root_nodes.iter().map(|id| { // let raw = id.0; // quote! { TemplateNodeId(#raw) } // }); // let node_mapping_quoted = node_mapping.iter().map(|op| match op { // Some(id) => { // let raw_id = id.0; // quote! {Some(TemplateNodeId(#raw_id))} // } // None => quote! {None}, // }); // let text_mapping_quoted = text_mapping.iter().map(|inner| { // let raw = inner.iter().map(|id| id.0); // quote! {&[#(TemplateNodeId(#raw)),*]} // }); // let attribute_mapping_quoted = attribute_mapping.iter().map(|inner| { // let raw = inner.iter().map(|(id, _)| id.0); // let indecies = inner.iter().map(|(_, idx)| idx); // quote! {&[#((TemplateNodeId(#raw), #indecies)),*]} // }); // let listener_mapping_quoted = listener_mapping.iter().map(|id| { // let raw = id.0; // quote! {TemplateNodeId(#raw)} // }); // let mut nodes_quoted = TokenStream::new(); // for n in nodes { // n.to_tokens(&mut nodes_quoted); // quote! {,}.to_tokens(&mut nodes_quoted); // } // let dynamic_path = match self.dynamic_path() { // Some(seg) => { // let seg = quote_owned_segment(seg); // quote! {Some(#seg)} // } // None => quote! {None}, // }; // let quoted = quote! { // { // const __NODES: dioxus::prelude::StaticTemplateNodes = &[#nodes_quoted]; // const __TEXT_MAPPING: &'static [&'static [dioxus::prelude::TemplateNodeId]] = &[#(#text_mapping_quoted),*]; // const __ATTRIBUTE_MAPPING: &'static [&'static [(dioxus::prelude::TemplateNodeId, usize)]] = &[#(#attribute_mapping_quoted),*]; // const __ROOT_NODES: &'static [dioxus::prelude::TemplateNodeId] = &[#(#root_nodes),*]; // const __NODE_MAPPING: &'static [Option] = &[#(#node_mapping_quoted),*]; // const __NODES_WITH_LISTENERS: &'static [dioxus::prelude::TemplateNodeId] = &[#(#listener_mapping_quoted),*]; // static __VOLITALE_MAPPING_INNER: dioxus::core::exports::once_cell::sync::Lazy> = dioxus::core::exports::once_cell::sync::Lazy::new(||{ // // check each property to see if it is volatile // let mut volatile = Vec::new(); // for n in __NODES { // if let TemplateNodeType::Element(el) = &n.node_type { // for (i, attr) in el.attributes.iter().enumerate() { // if attr.attribute.volatile { // volatile.push((n.id, i)); // } // } // } // } // volatile // }); // static __VOLITALE_MAPPING: &'static dioxus::core::exports::once_cell::sync::Lazy> = &__VOLITALE_MAPPING_INNER; // static __STATIC_VOLITALE_MAPPING: dioxus::prelude::LazyStaticVec<(dioxus::prelude::TemplateNodeId, usize)> = LazyStaticVec(__VOLITALE_MAPPING); // static __TEMPLATE: dioxus::prelude::Template = Template::Static(&StaticTemplate { // nodes: __NODES, // root_nodes: __ROOT_NODES, // dynamic_mapping: StaticDynamicNodeMapping::new(__NODE_MAPPING, __TEXT_MAPPING, __ATTRIBUTE_MAPPING, __STATIC_VOLITALE_MAPPING, __NODES_WITH_LISTENERS), // dynamic_path: #dynamic_path, // }); // let __bump = __cx.bump(); // __cx.template_ref(dioxus::prelude::TemplateId(get_line_num!()), __TEMPLATE.clone(), #dynamic_context) // } // }; // tokens.append_all(quoted) // } // } // #[derive(Default, Clone, Debug)] // pub struct DynamicTemplateContextBuilder { // nodes: Vec, // text: Vec, // attributes: Vec, // listeners: Vec<(String, Expr)>, // key: Option, // } // impl DynamicTemplateContextBuilder { // fn add_node(&mut self, node: BodyNode) -> usize { // let node_id = self.nodes.len(); // self.nodes.push(node); // node_id // } // fn add_text(&mut self, text: FormattedSegment) -> usize { // let text_id = self.text.len(); // self.text.push(text); // text_id // } // fn add_attr(&mut self, attr: TokenStream) -> usize { // let attr_id = self.attributes.len(); // self.attributes.push(attr); // attr_id // } // fn add_listener(&mut self, name: Ident, listener: Expr) -> usize { // let listener_id = self.listeners.len(); // self.listeners.push((name.to_string(), listener)); // listener_id // } // fn add_key(&mut self, key: TokenStream) { // self.key = Some(key); // } // } // impl ToTokens for DynamicTemplateContextBuilder { // fn to_tokens(&self, tokens: &mut TokenStream) { // let nodes = &self.nodes; // let text = &self.text; // let attributes = &self.attributes; // let listeners_names = self // .listeners // .iter() // .map(|(n, _)| syn::parse_str::(n).expect(n)); // let listeners_exprs = self.listeners.iter().map(|(_, e)| e); // let key = match &self.key { // Some(k) => quote!(Some(#k)), // None => quote!(None), // }; // tokens.append_all(quote! { // TemplateContext { // nodes: __cx.bump().alloc([#(#nodes),*]), // text_segments: __cx.bump().alloc([#(&*dioxus::core::exports::bumpalo::format!(in __bump, "{}", #text).into_bump_str()),*]), // attributes: __cx.bump().alloc([#({#attributes}.into_value(__cx.bump())),*]), // listeners: __cx.bump().alloc([#(dioxus_elements::on::#listeners_names(__cx, #listeners_exprs)),*]), // key: #key, // } // }) // } // } // fn quote_owned_segment(seg: OwnedPathSeg) -> proc_macro2::TokenStream { // let OwnedPathSeg { ops, traverse } = seg; // let ops = ops // .into_iter() // .map(|op| match op { // UpdateOp::StoreNode(id) => { // let id = quote_template_node_id(id); // quote!(UpdateOp::StoreNode(#id)) // } // UpdateOp::InsertBefore(id) => { // let id = quote_template_node_id(id); // quote!(UpdateOp::InsertBefore(#id)) // } // UpdateOp::InsertAfter(id) => { // let id = quote_template_node_id(id); // quote!(UpdateOp::InsertAfter(#id)) // } // UpdateOp::AppendChild(id) => { // let id = quote_template_node_id(id); // quote!(UpdateOp::AppendChild(#id)) // } // }) // .collect::>(); // let traverse = quote_owned_traverse(traverse); // quote! { // StaticPathSeg { // ops: &[#(#ops),*], // traverse: #traverse, // } // } // } // fn quote_owned_traverse(traverse: OwnedTraverse) -> proc_macro2::TokenStream { // match traverse { // OwnedTraverse::Halt => { // quote! {StaticTraverse::Halt} // } // OwnedTraverse::FirstChild(seg) => { // let seg = quote_owned_segment(*seg); // quote! {StaticTraverse::FirstChild(&#seg)} // } // OwnedTraverse::NextSibling(seg) => { // let seg = quote_owned_segment(*seg); // quote! {StaticTraverse::NextSibling(&#seg)} // } // OwnedTraverse::Both(b) => { // let (child, sibling) = *b; // let child = quote_owned_segment(child); // let sibling = quote_owned_segment(sibling); // quote! {StaticTraverse::Both(&(#child, #sibling))} // } // } // } // fn quote_template_node_id(id: TemplateNodeId) -> proc_macro2::TokenStream { // let raw = id.0; // quote! { // TemplateNodeId(#raw) // } // }