diff --git a/packages/rsx/src/attribute.rs b/packages/rsx/src/attribute.rs index 97cc15673..b6c6f94fb 100644 --- a/packages/rsx/src/attribute.rs +++ b/packages/rsx/src/attribute.rs @@ -155,7 +155,7 @@ impl ToTokens for ElementAttrValue { impl ElementAttrValue { fn to_str_expr(&self) -> Option { 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, diff --git a/packages/rsx/src/component.rs b/packages/rsx/src/component.rs index d703ccb51..1865f9857 100644 --- a/packages/rsx/src/component.rs +++ b/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) diff --git a/packages/rsx/src/ifmt.rs b/packages/rsx/src/ifmt.rs index fa764bf2e..29ce91a26 100644 --- a/packages/rsx/src/ifmt.rs +++ b/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 { + 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)* diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index 20fa935fd..4d2beaa2e 100644 --- a/packages/rsx/src/lib.rs +++ b/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 }, }; diff --git a/packages/rsx/src/node.rs b/packages/rsx/src/node.rs index 45816191b..3d98031ba 100644 --- a/packages/rsx/src/node.rs +++ b/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! { {