浏览代码

look out for a simple to optimize format case

Evan Almloff 1 年之前
父节点
当前提交
c9bd5a4e6e
共有 5 个文件被更改,包括 46 次插入5 次删除
  1. 1 1
      packages/rsx/src/attribute.rs
  2. 1 1
      packages/rsx/src/component.rs
  3. 42 1
      packages/rsx/src/ifmt.rs
  4. 1 1
      packages/rsx/src/lib.rs
  5. 1 1
      packages/rsx/src/node.rs

+ 1 - 1
packages/rsx/src/attribute.rs

@@ -155,7 +155,7 @@ impl ToTokens for ElementAttrValue {
 impl ElementAttrValue {
     fn to_str_expr(&self) -> Option<TokenStream2> {
         match self {
-            ElementAttrValue::AttrLiteral(lit) => Some(quote!(#lit.to_string())),
+            ElementAttrValue::AttrLiteral(lit) => Some(quote!(#lit)),
             ElementAttrValue::AttrOptionalExpr { value, .. } => value.to_str_expr(),
             ElementAttrValue::AttrExpr(expr) => Some(quote!(#expr.to_string())),
             _ => None,

+ 1 - 1
packages/rsx/src/component.rs

@@ -217,7 +217,7 @@ impl ToTokens for ContentField {
         match self {
             ContentField::ManExpr(e) => e.to_tokens(tokens),
             ContentField::Formatted(s) => tokens.append_all(quote! {
-                #s.to_string()
+                #s
             }),
             ContentField::OnHandlerRaw(e) => tokens.append_all(quote! {
                 EventHandler::new(#e)

+ 42 - 1
packages/rsx/src/ifmt.rs

@@ -65,6 +65,41 @@ impl IfmtInput {
                 }
             })
     }
+
+    /// Try to convert this into a single _.to_string() call if possible
+    ///
+    /// Using "{single_expression}" is pretty common, but you don't need to go through the whole format! machinery for that, so we optimize it here.
+    fn try_to_string(&self) -> Option<TokenStream> {
+        let mut single_dynamic = None;
+        for segment in &self.segments {
+            match segment {
+                Segment::Literal(literal) => {
+                    if !literal.is_empty() {
+                        return None;
+                    }
+                }
+                Segment::Formatted(FormattedSegment {
+                    segment,
+                    format_args,
+                }) => {
+                    if format_args.is_empty() {
+                        match single_dynamic {
+                            Some(current_string) => {
+                                single_dynamic =
+                                    Some(quote!(#current_string + &segment.to_string()));
+                            }
+                            None => {
+                                single_dynamic = Some(quote!(#segment.to_string()));
+                            }
+                        }
+                    } else {
+                        return None;
+                    }
+                }
+            }
+        }
+        single_dynamic
+    }
 }
 
 impl FromStr for IfmtInput {
@@ -141,6 +176,12 @@ impl FromStr for IfmtInput {
 
 impl ToTokens for IfmtInput {
     fn to_tokens(&self, tokens: &mut TokenStream) {
+        // Try to turn it into a single _.to_string() call
+        if let Some(single_dynamic) = self.try_to_string() {
+            tokens.extend(single_dynamic);
+            return;
+        }
+
         // build format_literal
         let mut format_literal = String::new();
         let mut expr_counter = 0;
@@ -201,7 +242,7 @@ impl ToTokens for IfmtInput {
             .map(|ident| quote!(#ident = #ident));
 
         quote! {
-            format_args!(
+            format!(
                 #format_literal
                 #(, #positional_args)*
                 #(, #named_args)*

+ 1 - 1
packages/rsx/src/lib.rs

@@ -201,7 +201,7 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
         };
 
         let key_tokens = match key {
-            Some(tok) => quote! { Some( #tok.to_string() ) },
+            Some(tok) => quote! { Some( #tok ) },
             None => quote! { None },
         };
 

+ 1 - 1
packages/rsx/src/node.rs

@@ -122,7 +122,7 @@ impl ToTokens for BodyNode {
             BodyNode::Element(el) => el.to_tokens(tokens),
             BodyNode::Component(comp) => comp.to_tokens(tokens),
             BodyNode::Text(txt) => tokens.append_all(quote! {
-                ::dioxus::core::DynamicNode::Text(::dioxus::core::VText::new(#txt.to_string()))
+                ::dioxus::core::DynamicNode::Text(::dioxus::core::VText::new(#txt))
             }),
             BodyNode::RawExpr(exp) => tokens.append_all(quote! {
                 {