Demonthos 2 éve
szülő
commit
daeffd4149

+ 1 - 1
packages/core-macro/src/props/mod.rs

@@ -781,7 +781,7 @@ Finally, call `.build()` to create the instance of `{name}`.
             let arg_type = if field.builder_attr.strip_option {
                 field.type_from_inside_option(false).ok_or_else(|| {
                     Error::new_spanned(
-                        &field_type,
+                        field_type,
                         "can't `strip_option` - field is not `Option<...>`",
                     )
                 })?

+ 69 - 68
packages/core/src/diff.rs

@@ -157,7 +157,7 @@ impl<'b> DiffState<'b> {
             }
 
             (Component(old), Component(new)) => {
-                self.diff_component_nodes(*old, *new, old_node, new_node);
+                self.diff_component_nodes(old, new, old_node, new_node);
             }
 
             (Fragment(old), Fragment(new)) => {
@@ -181,8 +181,8 @@ impl<'b> DiffState<'b> {
             VNode::Placeholder(anchor) => self.create_anchor_node(anchor, node),
             VNode::Element(element) => self.create_element_node(element, node),
             VNode::Fragment(frag) => self.create_fragment_node(frag),
-            VNode::Component(component) => self.create_component_node(*component),
-            VNode::TemplateRef(temp) => self.create_template_ref_node(*temp, node),
+            VNode::Component(component) => self.create_component_node(component),
+            VNode::TemplateRef(temp) => self.create_template_ref_node(temp, node),
         }
     }
 
@@ -572,6 +572,7 @@ impl<'b> DiffState<'b> {
         self.diff_children(old.children, new.children);
     }
 
+    #[allow(clippy::too_many_lines)]
     fn diff_template_ref_nodes(
         &mut self,
         old: &'b VTemplateRef<'b>,
@@ -579,44 +580,6 @@ impl<'b> DiffState<'b> {
         old_node: &'b VNode<'b>,
         new_node: &'b VNode<'b>,
     ) {
-        if std::ptr::eq(old, new) {
-            return;
-        }
-
-        // if the templates are different, just rebuild it
-        if old.template_id != new.template_id
-            || self
-                .scopes
-                .template_resolver
-                .borrow()
-                .is_dirty(&new.template_id)
-        {
-            self.replace_node(old_node, new_node);
-            return;
-        }
-
-        // if the node is comming back not assigned, that means it was borrowed but removed
-        let root = match old.id.get() {
-            Some(id) => id,
-            None => self.scopes.reserve_node(new_node),
-        };
-
-        self.scopes.update_node(new_node, root);
-
-        new.id.set(Some(root));
-
-        self.element_stack.push(GlobalNodeId::VNodeId(root));
-
-        self.mutations.enter_template_ref(root);
-
-        let scope_bump = &self.current_scope_bump();
-
-        let template = {
-            let templates = self.scopes.templates.borrow();
-            templates.get(&new.template_id).unwrap().clone()
-        };
-        let template = template.borrow();
-
         fn diff_attributes<'b, Nodes, Attributes, V, Children, Listeners, TextSegments, Text>(
             nodes: &Nodes,
             ctx: (
@@ -652,23 +615,6 @@ impl<'b> DiffState<'b> {
             }
         }
 
-        // diff dynamic attributes
-        for (idx, (old_attr, new_attr)) in old
-            .dynamic_context
-            .attributes
-            .iter()
-            .zip(new.dynamic_context.attributes.iter())
-            .enumerate()
-        {
-            if old_attr != new_attr {
-                template.with_nodes(
-                    diff_attributes,
-                    diff_attributes,
-                    (&mut self.mutations, scope_bump, new, &template, idx),
-                );
-            }
-        }
-
         fn set_attribute<'b, Attributes, V, Children, Listeners, TextSegments, Text>(
             node: &TemplateNode<Attributes, V, Children, Listeners, TextSegments, Text>,
             ctx: (&mut Mutations<'b>, &'b Bump, &VTemplateRef<'b>, usize),
@@ -701,16 +647,6 @@ impl<'b> DiffState<'b> {
             }
         }
 
-        // set all volatile attributes
-        for (id, idx) in template.volatile_attributes() {
-            template.with_node(
-                id,
-                set_attribute,
-                set_attribute,
-                (&mut self.mutations, scope_bump, new, idx),
-            )
-        }
-
         fn diff_dynamic_node<'b, Attributes, V, Children, Listeners, TextSegments, Text>(
             node: &TemplateNode<Attributes, V, Children, Listeners, TextSegments, Text>,
             ctx: (&mut DiffState<'b>, &'b VNode<'b>, &'b VNode<'b>, ElementId),
@@ -732,6 +668,71 @@ impl<'b> DiffState<'b> {
             }
         }
 
+        if std::ptr::eq(old, new) {
+            return;
+        }
+
+        // if the templates are different, just rebuild it
+        if old.template_id != new.template_id
+            || self
+                .scopes
+                .template_resolver
+                .borrow()
+                .is_dirty(&new.template_id)
+        {
+            self.replace_node(old_node, new_node);
+            return;
+        }
+
+        // if the node is comming back not assigned, that means it was borrowed but removed
+        let root = match old.id.get() {
+            Some(id) => id,
+            None => self.scopes.reserve_node(new_node),
+        };
+
+        self.scopes.update_node(new_node, root);
+
+        new.id.set(Some(root));
+
+        self.element_stack.push(GlobalNodeId::VNodeId(root));
+
+        self.mutations.enter_template_ref(root);
+
+        let scope_bump = &self.current_scope_bump();
+
+        let template = {
+            let templates = self.scopes.templates.borrow();
+            templates.get(&new.template_id).unwrap().clone()
+        };
+        let template = template.borrow();
+
+        // diff dynamic attributes
+        for (idx, (old_attr, new_attr)) in old
+            .dynamic_context
+            .attributes
+            .iter()
+            .zip(new.dynamic_context.attributes.iter())
+            .enumerate()
+        {
+            if old_attr != new_attr {
+                template.with_nodes(
+                    diff_attributes,
+                    diff_attributes,
+                    (&mut self.mutations, scope_bump, new, &template, idx),
+                );
+            }
+        }
+
+        // set all volatile attributes
+        for (id, idx) in template.volatile_attributes() {
+            template.with_node(
+                id,
+                set_attribute,
+                set_attribute,
+                (&mut self.mutations, scope_bump, new, idx),
+            );
+        }
+
         // diff dynmaic nodes
         for (idx, (old_node, new_node)) in old
             .dynamic_context

+ 4 - 6
packages/core/src/dynamic_template_context.rs

@@ -26,7 +26,7 @@ impl<T> PartialEq for LazyStaticVec<T> {
 
 /// Stores what nodes depend on specific dynamic parts of the template to allow the diffing algorithm to jump to that part of the template instead of travering it
 /// This makes adding constant template nodes add no additional cost to diffing.
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
 pub struct DynamicNodeMapping<
     Nodes,
@@ -97,7 +97,7 @@ where
         }
     }
 
-    pub(crate) fn all_dynamic<'a>(&'a self) -> impl Iterator<Item = TemplateNodeId> + 'a {
+    pub(crate) fn all_dynamic(&self) -> impl Iterator<Item = TemplateNodeId> + '_ {
         self.nodes
             .as_ref()
             .iter()
@@ -106,16 +106,14 @@ where
                 self.text
                     .as_ref()
                     .iter()
-                    .map(|ids| ids.as_ref().iter())
-                    .flatten(),
+                    .flat_map(|ids| ids.as_ref().iter()),
             )
             .copied()
             .chain(
                 self.attributes
                     .as_ref()
                     .iter()
-                    .map(|ids| ids.as_ref().iter())
-                    .flatten()
+                    .flat_map(|ids| ids.as_ref().iter())
                     .map(|dynamic| dynamic.0),
             )
             .chain(self.nodes_with_listeners.as_ref().iter().copied())

+ 6 - 6
packages/core/src/nodes.rs

@@ -37,9 +37,9 @@ pub enum GlobalNodeId {
     VNodeId(ElementId),
 }
 
-impl Into<GlobalNodeId> for ElementId {
-    fn into(self) -> GlobalNodeId {
-        GlobalNodeId::VNodeId(self)
+impl From<ElementId> for GlobalNodeId {
+    fn from(id: ElementId) -> GlobalNodeId {
+        GlobalNodeId::VNodeId(id)
     }
 }
 
@@ -279,9 +279,9 @@ impl ElementId {
     }
 }
 
-impl Into<u64> for ElementId {
-    fn into(self) -> u64 {
-        self.0 as u64
+impl From<ElementId> for u64 {
+    fn from(el: ElementId) -> u64 {
+        el.0 as u64
     }
 }
 

+ 1 - 1
packages/core/src/scopes.rs

@@ -357,7 +357,7 @@ impl ScopeArena {
                                 (
                                     &nodes,
                                     &template_ref.dynamic_context,
-                                    &event,
+                                    event,
                                     &state,
                                     template_ref_id,
                                 ),

+ 24 - 32
packages/core/src/template.rs

@@ -264,9 +264,9 @@ pub struct TemplateId(pub CodeLocation);
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct RendererTemplateId(pub usize);
 
-impl Into<u64> for RendererTemplateId {
-    fn into(self) -> u64 {
-        self.0 as u64
+impl From<RendererTemplateId> for u64 {
+    fn from(id: RendererTemplateId) -> u64 {
+        id.0 as u64
     }
 }
 
@@ -278,9 +278,9 @@ impl Into<u64> for RendererTemplateId {
 #[cfg_attr(feature = "serialize", serde(transparent))]
 pub struct TemplateNodeId(pub usize);
 
-impl Into<u64> for TemplateNodeId {
-    fn into(self) -> u64 {
-        JS_MAX_INT / 2 + self.0 as u64
+impl From<TemplateNodeId> for u64 {
+    fn from(id: TemplateNodeId) -> u64 {
+        JS_MAX_INT / 2 + id.0 as u64
     }
 }
 
@@ -434,7 +434,7 @@ impl Template {
                     mutations.append_children(children_created);
                 }
                 TemplateNodeType::Text(text) => {
-                    let mut text_iter = text.segments.as_ref().into_iter();
+                    let mut text_iter = text.segments.as_ref().iter();
                     if let (Some(TextTemplateSegment::Static(txt)), None) =
                         (text_iter.next(), text_iter.next())
                     {
@@ -550,23 +550,20 @@ impl Template {
         }
     }
 
-    pub(crate) fn get_dynamic_nodes_for_text_index<'a>(
-        &'a self,
-        idx: usize,
-    ) -> &'a [TemplateNodeId] {
+    pub(crate) fn get_dynamic_nodes_for_text_index(&self, idx: usize) -> &[TemplateNodeId] {
         match self {
-            Template::Static(s) => s.dynamic_mapping.text[idx].as_ref(),
+            Template::Static(s) => s.dynamic_mapping.text[idx],
             #[cfg(any(feature = "hot-reload", debug_assertions))]
             Template::Owned(o) => o.dynamic_mapping.text[idx].as_ref(),
         }
     }
 
-    pub(crate) fn get_dynamic_nodes_for_attribute_index<'a>(
-        &'a self,
+    pub(crate) fn get_dynamic_nodes_for_attribute_index(
+        &self,
         idx: usize,
-    ) -> &'a [(TemplateNodeId, usize)] {
+    ) -> &[(TemplateNodeId, usize)] {
         match self {
-            Template::Static(s) => s.dynamic_mapping.attributes[idx].as_ref(),
+            Template::Static(s) => s.dynamic_mapping.attributes[idx],
             #[cfg(any(feature = "hot-reload", debug_assertions))]
             Template::Owned(o) => o.dynamic_mapping.attributes[idx].as_ref(),
         }
@@ -610,7 +607,7 @@ pub type OwnedRootNodes = Vec<TemplateNodeId>;
 /// Templates can only contain a limited subset of VNodes and keys are not needed, as diffing will be skipped.
 /// Dynamic parts of the Template are inserted into the VNode using the `TemplateContext` by traversing the tree in order and filling in dynamic parts
 /// This template node is generic over the storage of the nodes to allow for owned and &'static versions.
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[cfg_attr(
     all(feature = "serialize", any(feature = "hot-reload", debug_assertions)),
     derive(serde::Serialize, serde::Deserialize)
@@ -697,10 +694,9 @@ where
                     .set_text(scope_bump.alloc(new_text), self.id)
             }
             TemplateNodeType::DynamicNode(idx) => {
-                drop(self);
                 // this will only be triggered for root elements
                 let created =
-                    diff_state.create_node(&template_ref.dynamic_context.resolve_node(*idx));
+                    diff_state.create_node(template_ref.dynamic_context.resolve_node(*idx));
                 diff_state.mutations.replace_with(self.id, created as u32);
             }
         }
@@ -710,7 +706,7 @@ where
 }
 
 /// A template for an attribute
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 #[cfg_attr(
     all(feature = "serialize", any(feature = "hot-reload", debug_assertions)),
     derive(serde::Serialize, serde::Deserialize)
@@ -723,7 +719,7 @@ pub struct TemplateAttribute<V: TemplateValue> {
 }
 
 /// A template attribute value that is either dynamic or static
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 #[cfg_attr(
     all(feature = "serialize", any(feature = "hot-reload", debug_assertions)),
     derive(serde::Serialize, serde::Deserialize)
@@ -744,9 +740,9 @@ pub trait TemplateValue {
 impl TemplateValue for StaticAttributeValue {
     fn allocate<'b>(&self, bump: &'b Bump) -> AttributeValue<'b> {
         match self.clone() {
-            StaticAttributeValue::Text(txt) => AttributeValue::Text(bump.alloc_str(&txt)),
+            StaticAttributeValue::Text(txt) => AttributeValue::Text(bump.alloc_str(txt)),
             StaticAttributeValue::Bytes(bytes) => {
-                AttributeValue::Bytes(bump.alloc_slice_copy(&bytes))
+                AttributeValue::Bytes(bump.alloc_slice_copy(bytes))
             }
             StaticAttributeValue::Float32(f) => AttributeValue::Float32(f),
             StaticAttributeValue::Float64(f) => AttributeValue::Float64(f),
@@ -799,7 +795,7 @@ impl TemplateValue for OwnedAttributeValue {
 }
 
 /// The kind of node the template is.
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[cfg_attr(
     all(feature = "serialize", any(feature = "hot-reload", debug_assertions)),
     derive(serde::Serialize, serde::Deserialize)
@@ -867,7 +863,7 @@ where
 type StaticStr = &'static str;
 
 /// A element template
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[cfg_attr(
     all(feature = "serialize", any(feature = "hot-reload", debug_assertions)),
     derive(serde::Serialize, serde::Deserialize)
@@ -931,7 +927,7 @@ where
 }
 
 /// A template for some text that may contain dynamic segments for example "Hello {name}" contains the static segment "Hello " and the dynamic segment "{name}".
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[cfg_attr(
     all(feature = "serialize", any(feature = "hot-reload", debug_assertions)),
     derive(serde::Serialize, serde::Deserialize)
@@ -961,7 +957,7 @@ where
 }
 
 /// A segment of a text template that may be dynamic or static.
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 #[cfg_attr(
     all(feature = "serialize", any(feature = "hot-reload", debug_assertions)),
     derive(serde::Serialize, serde::Deserialize)
@@ -1019,11 +1015,7 @@ impl TemplateResolver {
     }
 
     pub fn is_dirty(&self, id: &TemplateId) -> bool {
-        if let Some((_, true)) = self.template_id_mapping.get(id) {
-            true
-        } else {
-            false
-        }
+        matches!(self.template_id_mapping.get(id), Some((_, true)))
     }
 
     // returns (id, if the id was created)

+ 1 - 1
packages/core/src/virtual_dom.rs

@@ -727,7 +727,7 @@ impl VirtualDom {
             .borrow()
             .get(id)
             .map(|inner| {
-                let borrow = &*inner;
+                let borrow = inner;
                 f(&borrow.borrow())
             })
             .unwrap()

+ 1 - 1
packages/desktop/src/desktop_context.rs

@@ -189,7 +189,7 @@ pub(super) fn handler(
         MaximizeToggle => window.set_maximized(!window.is_maximized()),
         Fullscreen(state) => {
             if let Some(handle) = window.current_monitor() {
-                window.set_fullscreen(state.then(|| WryFullscreen::Borderless(Some(handle))));
+                window.set_fullscreen(state.then_some(WryFullscreen::Borderless(Some(handle))));
             }
         }
         FocusWindow => window.set_focus(),

+ 1 - 1
packages/desktop/src/protocol.rs

@@ -113,7 +113,7 @@ fn get_mime_from_path(trimmed: &str) -> Result<&str> {
         return Ok("image/svg+xml");
     }
 
-    let res = match infer::get_from_path(&trimmed)?.map(|f| f.mime_type()) {
+    let res = match infer::get_from_path(trimmed)?.map(|f| f.mime_type()) {
         Some(t) if t == "text/plain" => get_mime_by_ext(trimmed),
         Some(f) => f,
         None => get_mime_by_ext(trimmed),

+ 1 - 1
packages/native-core-macro/tests/update_state.rs

@@ -146,7 +146,7 @@ impl NodeDepState<()> for NodeStateTester {
                     iter.map(|a| {
                         (
                             a.attribute.name.to_string(),
-                            format!("{}", a.value.as_text().unwrap()),
+                            a.value.as_text().unwrap().to_string(),
                         )
                     })
                     .collect()

+ 4 - 4
packages/native-core/src/node_ref.rs

@@ -30,7 +30,7 @@ impl<'a> NodeView<'a> {
     pub fn tag(&self) -> Option<&'a str> {
         self.mask
             .tag
-            .then(|| match &self.inner.node_type {
+            .then_some(match &self.inner.node_type {
                 NodeType::Element { tag, .. } => Some(&**tag),
                 _ => None,
             })
@@ -41,8 +41,8 @@ impl<'a> NodeView<'a> {
     pub fn namespace(&self) -> Option<&'a str> {
         self.mask
             .namespace
-            .then(|| match &self.inner.node_type {
-                NodeType::Element { namespace, .. } => namespace.map(|s| &*s),
+            .then_some(match &self.inner.node_type {
+                NodeType::Element { namespace, .. } => *namespace,
                 _ => None,
             })
             .flatten()
@@ -68,7 +68,7 @@ impl<'a> NodeView<'a> {
     pub fn text(&self) -> Option<&str> {
         self.mask
             .text
-            .then(|| match &self.inner.node_type {
+            .then_some(match &self.inner.node_type {
                 NodeType::Text { text } => Some(&**text),
                 _ => None,
             })

+ 15 - 23
packages/native-core/src/real_dom.rs

@@ -449,11 +449,10 @@ impl<S: State> RealDom<S> {
             } => self
                 .nodes
                 .get(template_ref_id.0)
-                .map(|o| o.as_ref())
-                .flatten()
+                .and_then(|o| o.as_ref())
                 .and_then(|t| match &**t {
                     TemplateRefOrNode::Ref { nodes, .. } => {
-                        nodes.get(template_node_id.0).map(|o| o.as_ref()).flatten()
+                        nodes.get(template_node_id.0).and_then(|o| o.as_ref())
                     }
                     TemplateRefOrNode::Node(_) => None,
                 })
@@ -461,8 +460,7 @@ impl<S: State> RealDom<S> {
             GlobalNodeId::VNodeId(n) => self
                 .nodes
                 .get(n.0)
-                .map(|o| o.as_ref())
-                .flatten()
+                .and_then(|o| o.as_ref())
                 .and_then(|n| match &**n {
                     TemplateRefOrNode::Ref { .. } => None,
                     TemplateRefOrNode::Node(_) => Some(n),
@@ -522,6 +520,7 @@ impl<S: State> RealDom<S> {
         }
         let mut created = false;
         if let GlobalNodeId::VNodeId(id) = child_id {
+            #[allow(clippy::transmute_ptr_to_ref)]
             let unbounded_self: &mut Self = unsafe { std::mem::transmute(&*self as *const Self) };
             if let TemplateRefOrNode::Ref { roots, .. } = &**self.nodes[id.0].as_mut()? {
                 // this is safe because we know that no parent will be it's own child
@@ -569,8 +568,7 @@ impl<S: State> RealDom<S> {
                     };
                     nodes
                         .get_mut(template_node_id.0)
-                        .map(|n| n.as_mut())
-                        .flatten()
+                        .and_then(|n| n.as_mut())
                         .map(|n| n.as_mut())
                         .unwrap()
                 };
@@ -624,8 +622,7 @@ impl<S: State> RealDom<S> {
                     };
                     nodes
                         .get_mut(template_node_id.0)
-                        .map(|n| n.as_mut())
-                        .flatten()
+                        .and_then(|n| n.as_mut())
                         .map(|n| n.as_mut())
                         .unwrap()
                 };
@@ -764,7 +761,7 @@ impl<S: State> RealDom<S> {
                                         && self[GlobalNodeId::VNodeId(c.mounted_id())]
                                             .node_data
                                             .parent
-                                            == e.id.get().map(|id| GlobalNodeId::VNodeId(id))
+                                            == e.id.get().map(GlobalNodeId::VNodeId)
                                 })
                                 && attributes
                                     .iter()
@@ -880,11 +877,11 @@ impl<S: State> RealDom<S> {
         }
     }
 
-    pub fn split<'a>(
-        &'a mut self,
+    pub fn split(
+        &mut self,
     ) -> (
-        impl Traversable<Id = GlobalNodeId, Node = S> + 'a,
-        impl Traversable<Id = GlobalNodeId, Node = NodeData> + 'a,
+        impl Traversable<Id = GlobalNodeId, Node = S> + '_,
+        impl Traversable<Id = GlobalNodeId, Node = NodeData> + '_,
     ) {
         let raw = self as *mut Self;
         // this is safe beacuse the traversable trait does not allow mutation of the position of elements, and within elements the access is disjoint.
@@ -1055,8 +1052,7 @@ impl<T: State> Traversable for RealDom<T> {
 
                     nodes
                         .get(template_node_id.0)
-                        .map(|n| n.as_ref())
-                        .flatten()
+                        .and_then(|n| n.as_ref())
                         .map(|n| n.as_ref())
                 }
             }
@@ -1086,8 +1082,7 @@ impl<T: State> Traversable for RealDom<T> {
 
                     nodes
                         .get_mut(template_node_id.0)
-                        .map(|n| n.as_mut())
-                        .flatten()
+                        .and_then(|n| n.as_mut())
                         .map(|n| n.as_mut())
                 }
             }
@@ -1097,7 +1092,7 @@ impl<T: State> Traversable for RealDom<T> {
     fn children(&self, id: Self::Id) -> &[Self::Id] {
         if let Some(node) = <Self as Traversable>::get(self, id) {
             match &node.node_data.node_type {
-                NodeType::Element { children, .. } => &children,
+                NodeType::Element { children, .. } => children,
                 _ => &[],
             }
         } else {
@@ -1123,10 +1118,7 @@ impl<T: State> Traversable for RealDom<T> {
                         TemplateRefOrNode::Node(_) => panic!("Expected template ref"),
                     };
 
-                    nodes
-                        .get(template_node_id.0)
-                        .map(|n| n.as_deref())
-                        .flatten()
+                    nodes.get(template_node_id.0).and_then(|n| n.as_deref())
                 }?
                 .node_data
                 .parent

+ 3 - 5
packages/rsx/src/component.rs

@@ -242,11 +242,9 @@ impl Parse for ComponentField {
             let forked = input.fork();
             let t: LitStr = forked.parse()?;
             // the string literal must either be the end of the input or a followed by a comma
-            if forked.is_empty() || forked.peek(Token![,]) {
-                if is_literal_foramtted(&t) {
-                    let content = ContentField::Formatted(input.parse()?);
-                    return Ok(Self { name, content });
-                }
+            if (forked.is_empty() || forked.peek(Token![,])) && is_literal_foramtted(&t) {
+                let content = ContentField::Formatted(input.parse()?);
+                return Ok(Self { name, content });
             }
         }
 

+ 3 - 1
packages/rsx/src/elements.rs

@@ -66,8 +66,10 @@ macro_rules! builder_constructors {
     };
 }
 
+type MappedAttributes = &'static [(&'static str, &'static [(&'static str, &'static str, bool)])];
+
 /// All attributes that are tied to a specific element that either have a different name, or are volitile
-pub const ELEMENTS_WITH_MAPPED_ATTRIBUTES: &[(&str, &[(&str, &str, bool)])] = &[
+pub const ELEMENTS_WITH_MAPPED_ATTRIBUTES: MappedAttributes = &[
     (
         "script",
         &[("r#type", "type", false), ("r#script", "script", false)],

+ 5 - 5
packages/rsx/src/error.rs

@@ -12,11 +12,11 @@ pub enum Error {
 
 #[derive(Debug, Serialize, Deserialize)]
 pub enum RecompileReason {
-    CapturedVariable(String),
-    CapturedExpression(String),
-    CapturedComponent(String),
-    CapturedListener(String),
-    CapturedAttribute(String),
+    Variable(String),
+    Expression(String),
+    Component(String),
+    Listener(String),
+    Attribute(String),
 }
 
 #[derive(Debug, Serialize, Deserialize)]

+ 59 - 89
packages/rsx/src/template.rs

@@ -21,7 +21,7 @@ pub fn try_parse_template(
         template_builder = template_builder
             .try_switch_dynamic_context(prev)
             .ok_or_else(|| {
-                Error::RecompileRequiredError(RecompileReason::CapturedVariable(
+                Error::RecompileRequiredError(RecompileReason::Variable(
                     "dynamic context updated".to_string(),
                 ))
             })?;
@@ -57,20 +57,17 @@ struct TemplateElementBuilder {
     parent: Option<TemplateNodeId>,
 }
 
+#[cfg(any(feature = "hot-reload", debug_assertions))]
+type OwndedTemplateElement = TemplateElement<
+    Vec<TemplateAttribute<OwnedAttributeValue>>,
+    OwnedAttributeValue,
+    Vec<TemplateNodeId>,
+    Vec<usize>,
+>;
+
 impl TemplateElementBuilder {
     #[cfg(any(feature = "hot-reload", debug_assertions))]
-    fn try_into_owned(
-        self,
-        location: &OwnedCodeLocation,
-    ) -> Result<
-        TemplateElement<
-            Vec<TemplateAttribute<OwnedAttributeValue>>,
-            OwnedAttributeValue,
-            Vec<TemplateNodeId>,
-            Vec<usize>,
-        >,
-        Error,
-    > {
+    fn try_into_owned(self, location: &OwnedCodeLocation) -> Result<OwndedTemplateElement, Error> {
         let Self {
             tag,
             attributes,
@@ -163,9 +160,7 @@ impl TemplateAttributeBuilder {
             .ok_or_else(|| {
                 if literal {
                     // literals will be captured when a full recompile is triggered
-                    Error::RecompileRequiredError(RecompileReason::CapturedAttribute(
-                        name.to_string(),
-                    ))
+                    Error::RecompileRequiredError(RecompileReason::Attribute(name.to_string()))
                 } else {
                     Error::ParseError(ParseError::new(
                         syn::Error::new(span, format!("unknown attribute: {}", name)),
@@ -253,22 +248,19 @@ enum TemplateNodeTypeBuilder {
     DynamicNode(usize),
 }
 
+#[cfg(any(feature = "hot-reload", debug_assertions))]
+type OwnedTemplateNodeType = TemplateNodeType<
+    Vec<TemplateAttribute<OwnedAttributeValue>>,
+    OwnedAttributeValue,
+    Vec<TemplateNodeId>,
+    Vec<usize>,
+    Vec<TextTemplateSegment<String>>,
+    String,
+>;
+
 impl TemplateNodeTypeBuilder {
     #[cfg(any(feature = "hot-reload", debug_assertions))]
-    fn try_into_owned(
-        self,
-        location: &OwnedCodeLocation,
-    ) -> Result<
-        TemplateNodeType<
-            Vec<TemplateAttribute<OwnedAttributeValue>>,
-            OwnedAttributeValue,
-            Vec<TemplateNodeId>,
-            Vec<usize>,
-            Vec<TextTemplateSegment<String>>,
-            String,
-        >,
-        Error,
-    > {
+    fn try_into_owned(self, location: &OwnedCodeLocation) -> Result<OwnedTemplateNodeType, Error> {
         match self {
             TemplateNodeTypeBuilder::Element(el) => {
                 Ok(TemplateNodeType::Element(el.try_into_owned(location)?))
@@ -382,13 +374,11 @@ impl TemplateBuilder {
         }
 
         // only build a template if there is at least one static node
-        if builder.nodes.iter().all(|r| {
-            if let TemplateNodeTypeBuilder::DynamicNode(_) = &r.node_type {
-                true
-            } else {
-                false
-            }
-        }) {
+        if builder
+            .nodes
+            .iter()
+            .all(|r| matches!(&r.node_type, TemplateNodeTypeBuilder::DynamicNode(_)))
+        {
             None
         } else {
             Some(builder)
@@ -649,50 +639,40 @@ impl TemplateBuilder {
         let mut node_mapping = vec![None; dynamic_context.nodes.len()];
         let nodes = &self.nodes;
         for n in nodes {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::DynamicNode(idx) => node_mapping[*idx] = Some(n.id),
-                _ => (),
+            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 {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::Text(txt) => {
-                    for seg in &txt.segments {
-                        match seg {
-                            TextTemplateSegment::Static(_) => (),
-                            TextTemplateSegment::Dynamic(idx) => text_mapping[*idx].push(n.id),
-                        }
+            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 {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::Element(el) => {
-                    for (i, attr) in el.attributes.iter().enumerate() {
-                        match attr.value {
-                            TemplateAttributeValue::Static(_) => (),
-                            TemplateAttributeValue::Dynamic(idx) => {
-                                attribute_mapping[idx].push((n.id, i));
-                            }
+            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 {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::Element(el) => {
-                    if !el.listeners.is_empty() {
-                        listener_mapping.push(n.id);
-                    }
+            if let TemplateNodeTypeBuilder::Element(el) = &n.node_type {
+                if !el.listeners.is_empty() {
+                    listener_mapping.push(n.id);
                 }
-                _ => (),
             }
         }
 
@@ -727,50 +707,40 @@ impl ToTokens for TemplateBuilder {
 
         let mut node_mapping = vec![None; dynamic_context.nodes.len()];
         for n in nodes {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::DynamicNode(idx) => node_mapping[*idx] = Some(n.id),
-                _ => (),
+            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 {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::Text(txt) => {
-                    for seg in &txt.segments {
-                        match seg {
-                            TextTemplateSegment::Static(_) => (),
-                            TextTemplateSegment::Dynamic(idx) => text_mapping[*idx].push(n.id),
-                        }
+            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 {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::Element(el) => {
-                    for (i, attr) in el.attributes.iter().enumerate() {
-                        match attr.value {
-                            TemplateAttributeValue::Static(_) => (),
-                            TemplateAttributeValue::Dynamic(idx) => {
-                                attribute_mapping[idx].push((n.id, i));
-                            }
+            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 {
-            match &n.node_type {
-                TemplateNodeTypeBuilder::Element(el) => {
-                    if !el.listeners.is_empty() {
-                        listener_mapping.push(n.id);
-                    }
+            if let TemplateNodeTypeBuilder::Element(el) = &n.node_type {
+                if !el.listeners.is_empty() {
+                    listener_mapping.push(n.id);
                 }
-                _ => (),
             }
         }
 

+ 33 - 72
packages/ssr/src/lib.rs

@@ -69,7 +69,6 @@ pub fn render_lazy<'a>(f: LazyNodes<'a, '_>) -> String {
     };
     let r = ssr_renderer.to_string();
     drop(ssr_renderer);
-    drop(vdom);
     r
 }
 
@@ -247,7 +246,6 @@ impl<'a: 'c, 'c> TextRenderer<'a, '_, 'c> {
                                         &s.nodes,
                                         &s.nodes[r.0],
                                         dynamic_context,
-                                        &s.dynamic_mapping,
                                         f,
                                         last_node_was_text,
                                         il,
@@ -260,7 +258,6 @@ impl<'a: 'c, 'c> TextRenderer<'a, '_, 'c> {
                                         &o.nodes,
                                         &o.nodes[r.0],
                                         dynamic_context,
-                                        &o.dynamic_mapping,
                                         f,
                                         last_node_was_text,
                                         il,
@@ -278,35 +275,11 @@ impl<'a: 'c, 'c> TextRenderer<'a, '_, 'c> {
         Ok(())
     }
 
-    fn render_template_node<
-        TemplateNodes,
-        Attributes,
-        V,
-        Children,
-        Listeners,
-        TextSegments,
-        Text,
-        Nodes,
-        TextOuter,
-        TextInner,
-        AttributesOuter,
-        AttributesInner,
-        Volatile,
-        Listeners2,
-    >(
+    fn render_template_node<TemplateNodes, Attributes, V, Children, Listeners, TextSegments, Text>(
         &self,
         template_nodes: &TemplateNodes,
         node: &TemplateNode<Attributes, V, Children, Listeners, TextSegments, Text>,
         dynamic_context: &TemplateContext,
-        dynamic_node_mapping: &DynamicNodeMapping<
-            Nodes,
-            TextOuter,
-            TextInner,
-            AttributesOuter,
-            AttributesInner,
-            Volatile,
-            Listeners2,
-        >,
         f: &mut impl Write,
         last_node_was_text: &mut bool,
         il: u16,
@@ -315,18 +288,11 @@ impl<'a: 'c, 'c> TextRenderer<'a, '_, 'c> {
         TemplateNodes:
             AsRef<[TemplateNode<Attributes, V, Children, Listeners, TextSegments, Text>]>,
         Attributes: AsRef<[TemplateAttribute<V>]>,
-        AttributesInner: AsRef<[(TemplateNodeId, usize)]>,
-        AttributesOuter: AsRef<[AttributesInner]>,
         Children: AsRef<[TemplateNodeId]>,
         Listeners: AsRef<[usize]>,
-        Listeners2: AsRef<[TemplateNodeId]>,
-        Nodes: AsRef<[Option<TemplateNodeId>]>,
         Text: AsRef<str>,
-        TextInner: AsRef<[TemplateNodeId]>,
-        TextOuter: AsRef<[TextInner]>,
         TextSegments: AsRef<[TextTemplateSegment<Text>]>,
         V: TemplateValue,
-        Volatile: AsRef<[(TemplateNodeId, usize)]>,
     {
         match &node.node_type {
             TemplateNodeType::Element(el) => {
@@ -342,7 +308,7 @@ impl<'a: 'c, 'c> TextRenderer<'a, '_, 'c> {
 
                 let mut inner_html = None;
 
-                let mut attr_iter = el.attributes.as_ref().into_iter().peekable();
+                let mut attr_iter = el.attributes.as_ref().iter().peekable();
 
                 while let Some(attr) = attr_iter.next() {
                     match attr.attribute.namespace {
@@ -433,7 +399,6 @@ impl<'a: 'c, 'c> TextRenderer<'a, '_, 'c> {
                             template_nodes,
                             &template_nodes.as_ref()[child.0],
                             dynamic_context,
-                            dynamic_node_mapping,
                             f,
                             &mut last_node_was_text,
                             il + 1,
@@ -497,10 +462,8 @@ where
                 if attr.attribute.name == "dangerous_inner_html" {
                     inner_html = Some(attr.value.as_text().unwrap())
                 } else {
-                    if is_boolean_attribute(attr.attribute.name) {
-                        if !attr.value.is_truthy() {
-                            continue;
-                        }
+                    if is_boolean_attribute(attr.attribute.name) && !attr.value.is_truthy() {
+                        continue;
                     }
                     write!(f, " {}=\"{}\"", attr.attribute.name, attr.value)?
                 }
@@ -527,37 +490,35 @@ where
 }
 
 fn is_boolean_attribute(attribute: &'static str) -> bool {
-    if let "allowfullscreen"
-    | "allowpaymentrequest"
-    | "async"
-    | "autofocus"
-    | "autoplay"
-    | "checked"
-    | "controls"
-    | "default"
-    | "defer"
-    | "disabled"
-    | "formnovalidate"
-    | "hidden"
-    | "ismap"
-    | "itemscope"
-    | "loop"
-    | "multiple"
-    | "muted"
-    | "nomodule"
-    | "novalidate"
-    | "open"
-    | "playsinline"
-    | "readonly"
-    | "required"
-    | "reversed"
-    | "selected"
-    | "truespeed" = attribute
-    {
-        true
-    } else {
-        false
-    }
+    matches!(
+        attribute,
+        "allowfullscreen"
+            | "allowpaymentrequest"
+            | "async"
+            | "autofocus"
+            | "autoplay"
+            | "checked"
+            | "controls"
+            | "default"
+            | "defer"
+            | "disabled"
+            | "formnovalidate"
+            | "hidden"
+            | "ismap"
+            | "itemscope"
+            | "loop"
+            | "multiple"
+            | "muted"
+            | "nomodule"
+            | "novalidate"
+            | "open"
+            | "playsinline"
+            | "readonly"
+            | "required"
+            | "reversed"
+            | "selected"
+            | "truespeed"
+    )
 }
 
 #[derive(Clone, Debug, Default)]

+ 1 - 1
packages/tui/src/focus.rs

@@ -93,7 +93,7 @@ impl NodeDepState<()> for Focus {
                 .map(|mut listeners| {
                     listeners
                         .any(|l| FOCUS_EVENTS.binary_search(&l).is_ok())
-                        .then(|| ())
+                        .then_some(())
                 })
                 .is_some()
             {

+ 1 - 1
packages/tui/src/layout.rs

@@ -94,7 +94,7 @@ impl ChildDepState for TaffyLayout {
                         .binary_search(&attribute.name.as_ref())
                         .is_ok());
                     if let Some(text) = value.as_text() {
-                        apply_layout_attributes(&&attribute.name, text, &mut style);
+                        apply_layout_attributes(&attribute.name, text, &mut style);
                     }
                 }
             }

+ 2 - 2
packages/web/src/dom.rs

@@ -230,7 +230,7 @@ fn virtual_event_from_websys_event(
         // todo: these handlers might get really slow if the input box gets large and allocation pressure is heavy
         // don't have a good solution with the serialized event problem
         "change" | "input" | "invalid" | "reset" | "submit" => {
-            let value: String = (&target)
+            let value: String = target
                 .dyn_ref()
                 .map(|input: &web_sys::HtmlInputElement| {
                     // todo: special case more input types
@@ -273,7 +273,7 @@ fn virtual_event_from_websys_event(
                 for x in 0..elements.length() {
                     let element = elements.item(x).unwrap();
                     if let Some(name) = element.get_attribute("name") {
-                        let value: Option<String> = (&element)
+                        let value: Option<String> = element
                                 .dyn_ref()
                                 .map(|input: &web_sys::HtmlInputElement| {
                                     match input.type_().as_str() {