From 90d0164b9eaa0c97ae238315e6766e5902d300fc Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 16 Jan 2024 12:47:23 -0600 Subject: [PATCH] fix formatted strings in components --- examples/pattern_model.rs | 56 ++++--------------- examples/tasks.rs | 5 +- examples/todomvc.rs | 2 +- .../inline_props.rs | 7 +-- packages/core-macro/src/props/mod.rs | 22 +++++++- packages/rsx/src/attribute.rs | 4 +- packages/rsx/src/ifmt.rs | 2 +- packages/rsx/src/node.rs | 2 +- 8 files changed, 41 insertions(+), 59 deletions(-) diff --git a/examples/pattern_model.rs b/examples/pattern_model.rs index 8b6179466..27233c9f8 100644 --- a/examples/pattern_model.rs +++ b/examples/pattern_model.rs @@ -44,38 +44,22 @@ fn app() -> Element { style { {STYLE} } div { id: "wrapper", div { class: "app", - div { class: "calculator", onkeypress: move |evt| state.write().handle_keydown(evt), + div { + class: "calculator", + onkeypress: move |evt| state.write().handle_keydown(evt), div { class: "calculator-display", {state.read().formatted_display()} } div { class: "calculator-keypad", div { class: "input-keys", div { class: "function-keys", - CalculatorKey { - name: "key-clear", - onclick: move |_| state.write().clear_display(), + CalculatorKey { name: "key-clear", onclick: move |_| state.write().clear_display(), if state.read().display_value == "0" { "C" } else { "AC" } } - CalculatorKey { - name: "key-sign", - onclick: move |_| state.write().toggle_sign(), - "±" - } - CalculatorKey { - name: "key-percent", - onclick: move |_| state.write().toggle_percent(), - "%" - } + CalculatorKey { name: "key-sign", onclick: move |_| state.write().toggle_sign(), "±" } + CalculatorKey { name: "key-percent", onclick: move |_| state.write().toggle_percent(), "%" } } div { class: "digit-keys", - CalculatorKey { - name: "key-0", - onclick: move |_| state.write().input_digit(0), - "0" - } - CalculatorKey { - name: "key-dot", - onclick: move |_| state.write().input_dot(), - "●" - } + CalculatorKey { name: "key-0", onclick: move |_| state.write().input_digit(0), "0" } + CalculatorKey { name: "key-dot", onclick: move |_| state.write().input_dot(), "●" } for k in 1..10 { CalculatorKey { key: "{k}", @@ -102,16 +86,8 @@ fn app() -> Element { onclick: move |_| state.write().set_operator(Operator::Sub), "−" } - CalculatorKey { - name: "key-add", - onclick: move |_| state.write().set_operator(Operator::Add), - "+" - } - CalculatorKey { - name: "key-equals", - onclick: move |_| state.write().perform_operation(), - "=" - } + CalculatorKey { name: "key-add", onclick: move |_| state.write().set_operator(Operator::Add), "+" } + CalculatorKey { name: "key-equals", onclick: move |_| state.write().perform_operation(), "=" } } } } @@ -121,17 +97,9 @@ fn app() -> Element { } #[component] -fn CalculatorKey( - #[props(into)] name: String, - onclick: EventHandler, - children: Element, -) -> Element { +fn CalculatorKey(name: String, onclick: EventHandler, children: Element) -> Element { render! { - button { - class: "calculator-key {name}", - onclick: move |e| onclick.call(e), - {&children} - } + button { class: "calculator-key {name}", onclick: move |e| onclick.call(e), {&children} } } } diff --git a/examples/tasks.rs b/examples/tasks.rs index 3df04f6f7..e5f51a2b0 100644 --- a/examples/tasks.rs +++ b/examples/tasks.rs @@ -22,10 +22,7 @@ fn app() -> Element { render! { div { h1 { "Current count: {count}" } - button { - onclick: move |_| count.set(0), - "Reset the count" - } + button { onclick: move |_| count.set(0), "Reset the count" } } } } diff --git a/examples/todomvc.rs b/examples/todomvc.rs index 221e068bd..34d845fbf 100644 --- a/examples/todomvc.rs +++ b/examples/todomvc.rs @@ -120,7 +120,7 @@ pub fn TodoEntry(mut todos: Signal>, id: u32) -> Element let contents = use_selector(move || todos.read().get(&id).unwrap().contents.clone()); render! { - li { class: if checked() { "completed" }, class: if is_editing() { "editing"}, + li { class: if checked() { "completed" }, class: if is_editing() { "editing" }, div { class: "view", input { class: "toggle", diff --git a/packages/core-macro/src/component_body_deserializers/inline_props.rs b/packages/core-macro/src/component_body_deserializers/inline_props.rs index c9a2ae847..6b9f2b599 100644 --- a/packages/core-macro/src/component_body_deserializers/inline_props.rs +++ b/packages/core-macro/src/component_body_deserializers/inline_props.rs @@ -261,11 +261,8 @@ fn get_function(component_body: &ComponentBody) -> ItemFn { let mut pat = pat.clone(); // rip off mutability, but still write it out eventually - match pat.as_mut() { - Pat::Ident(ref mut pat_ident) => { - pat_ident.mutability = None; - } - _ => {} + if let Pat::Ident(ref mut pat_ident) = pat.as_mut() { + pat_ident.mutability = None; } Some(quote!(mut #pat)) diff --git a/packages/core-macro/src/props/mod.rs b/packages/core-macro/src/props/mod.rs index 572f98832..b6d9173f1 100644 --- a/packages/core-macro/src/props/mod.rs +++ b/packages/core-macro/src/props/mod.rs @@ -173,7 +173,7 @@ mod field_info { use quote::quote; use syn::spanned::Spanned; use syn::{parse::Error, punctuated::Punctuated}; - use syn::{Expr, Path}; + use syn::{parse_quote, Expr, Path}; use super::util::{ expr_to_single_string, ident_to_type, path_to_single_string, strip_raw_ident_prefix, @@ -204,6 +204,15 @@ mod field_info { ); } + // String fields automatically use impl Display + if field.ty == parse_quote!(::std::string::String) + || field.ty == parse_quote!(std::string::String) + || field.ty == parse_quote!(string::String) + || field.ty == parse_quote!(String) + { + builder_attr.from_displayable = true; + } + // extended field is automatically empty if !builder_attr.extends.is_empty() { builder_attr.default = Some( @@ -263,6 +272,7 @@ mod field_info { pub doc: Option, pub skip: bool, pub auto_into: bool, + pub from_displayable: bool, pub strip_option: bool, pub ignore_option: bool, pub extends: Vec, @@ -412,6 +422,7 @@ mod field_info { handle_fields!( "skip", skip, "skipped"; "into", auto_into, "calling into() on the argument"; + "displayable", from_displayable, "calling to_string() on the argument"; "strip_option", strip_option, "putting the argument in Some(...)"; ) } @@ -443,6 +454,10 @@ mod field_info { self.auto_into = false; Ok(()) } + "displayable" => { + self.from_displayable = false; + Ok(()) + } "optional" => { self.strip_option = false; self.ignore_option = true; @@ -954,6 +969,11 @@ Finally, call `.build()` to create the instance of `{name}`. quote!(impl ::core::convert::Into<#arg_type>), quote!(#field_name.into()), ) + } else if field.builder_attr.from_displayable { + ( + quote!(impl ::core::fmt::Display), + quote!(#field_name.to_string()), + ) } else { (quote!(#arg_type), quote!(#field_name)) }; diff --git a/packages/rsx/src/attribute.rs b/packages/rsx/src/attribute.rs index 4d9ebeb32..84d92cf8d 100644 --- a/packages/rsx/src/attribute.rs +++ b/packages/rsx/src/attribute.rs @@ -211,7 +211,7 @@ impl ToTokens for ElementAttrValue { fn to_tokens(&self, tokens: &mut TokenStream2) { match self { ElementAttrValue::Shorthand(i) => tokens.append_all(quote! { #i }), - ElementAttrValue::AttrLiteral(lit) => tokens.append_all(quote! { #lit }), + ElementAttrValue::AttrLiteral(lit) => tokens.append_all(quote! { #lit.to_string() }), ElementAttrValue::AttrOptionalExpr { condition, value } => { tokens.append_all(quote! { if #condition { Some(#value) } else { None } }) } @@ -224,7 +224,7 @@ impl ToTokens for ElementAttrValue { impl ElementAttrValue { fn to_str_expr(&self) -> Option { match self { - ElementAttrValue::AttrLiteral(lit) => Some(quote!(#lit)), + ElementAttrValue::AttrLiteral(lit) => Some(quote!(#lit.to_string())), ElementAttrValue::AttrOptionalExpr { value, .. } => value.to_str_expr(), ElementAttrValue::AttrExpr(expr) => Some(quote!(#expr.to_string())), _ => None, diff --git a/packages/rsx/src/ifmt.rs b/packages/rsx/src/ifmt.rs index 29ce91a26..e32e06472 100644 --- a/packages/rsx/src/ifmt.rs +++ b/packages/rsx/src/ifmt.rs @@ -242,7 +242,7 @@ impl ToTokens for IfmtInput { .map(|ident| quote!(#ident = #ident)); quote! { - format!( + ::std::format_args!( #format_literal #(, #positional_args)* #(, #named_args)* diff --git a/packages/rsx/src/node.rs b/packages/rsx/src/node.rs index ea64ad364..188858b29 100644 --- a/packages/rsx/src/node.rs +++ b/packages/rsx/src/node.rs @@ -144,7 +144,7 @@ impl ToTokens for BodyNode { } BodyNode::Component(comp) => comp.to_tokens(tokens), BodyNode::Text(txt) => tokens.append_all(quote! { - dioxus_core::DynamicNode::Text(dioxus_core::VText::new(#txt)) + dioxus_core::DynamicNode::Text(dioxus_core::VText::new(#txt.to_string())) }), BodyNode::RawExpr(exp) => tokens.append_all(quote! { {