From d1333a3402846002e45c8589ea542fc50cf88183 Mon Sep 17 00:00:00 2001 From: jclmnop Date: Sun, 22 Jan 2023 12:37:40 +0000 Subject: [PATCH] modify component attribute macro to allow snake_case fn names --- .gitignore | 1 + leptos/tests/ssr.rs | 34 ++++++++++++++++++++++++++++++++++ leptos_macro/Cargo.toml | 1 + leptos_macro/src/component.rs | 12 +++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fbe21a725..d6359fc3d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ blob.rs Cargo.lock **/*.rs.bk .DS_Store +.idea diff --git a/leptos/tests/ssr.rs b/leptos/tests/ssr.rs index d9bdc3d20..ddf1bdb7d 100644 --- a/leptos/tests/ssr.rs +++ b/leptos/tests/ssr.rs @@ -55,6 +55,40 @@ fn ssr_test_with_components() { }); } +#[cfg(not(any(feature = "csr", feature = "hydrate")))] +#[test] +fn ssr_test_with_snake_case_components() { + use leptos::*; + + #[component] + fn snake_case_counter(cx: Scope, initial_value: i32) -> impl IntoView { + let (value, set_value) = create_signal(cx, initial_value); + view! { + cx, +
+ + "Value: " {move || value.get().to_string()} "!" + +
+ } + } + + _ = create_scope(create_runtime(), |cx| { + let rendered = view! { + cx, +
+ + +
+ }; + + assert_eq!( + rendered.into_view(cx).render_to_string(cx), + "
Value: 1!
Value: 2!
" + ); + }); +} + #[cfg(not(any(feature = "csr", feature = "hydrate")))] #[test] fn test_classes() { diff --git a/leptos_macro/Cargo.toml b/leptos_macro/Cargo.toml index 9c3d7d196..61be4d48e 100644 --- a/leptos_macro/Cargo.toml +++ b/leptos_macro/Cargo.toml @@ -27,6 +27,7 @@ leptos_dom = { workspace = true } leptos_reactive = { workspace = true } leptos_server = { workspace = true } lazy_static = "1.4" +convert_case = "0.6.0" [dev-dependencies] log = "0.4" diff --git a/leptos_macro/src/component.rs b/leptos_macro/src/component.rs index d1c5dbd0f..46784213b 100644 --- a/leptos_macro/src/component.rs +++ b/leptos_macro/src/component.rs @@ -1,3 +1,4 @@ +use convert_case::{Case::{Snake, Pascal}, Casing}; use itertools::Itertools; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, ToTokens, TokenStreamExt}; @@ -75,7 +76,7 @@ impl Parse for Model { is_transparent: false, docs, vis: item.vis.clone(), - name: item.sig.ident.clone(), + name: convert_from_snake_case(&item.sig.ident), scope_name, props, ret: item.sig.output.clone(), @@ -97,6 +98,15 @@ fn drain_filter(vec: &mut Vec, mut some_predicate: impl FnMut(&mut T) -> b } } +fn convert_from_snake_case(name: &Ident) -> Ident { + let name_str = name.to_string(); + if !name_str.is_case(Snake) { + name.clone() + } else { + Ident::new(&*name_str.to_case(Pascal), name.span().clone()) + } +} + impl ToTokens for Model { fn to_tokens(&self, tokens: &mut TokenStream) { let Self {