From d1ba2ef82d7519d4a28e6d392303f49d89ff3d8c Mon Sep 17 00:00:00 2001 From: arctic_hen7 Date: Wed, 23 Mar 2022 19:58:55 +1100 Subject: [PATCH] feat: added component name inference to `template_rx` Can't do this with the old macro until the next breaking change. --- examples/.base/src/templates/index.rs | 2 +- examples/core/basic/src/templates/about.rs | 2 +- examples/core/basic/src/templates/index.rs | 2 +- .../src/templates/about.rs | 2 +- .../src/templates/index.rs | 2 +- .../core/global_state/src/templates/about.rs | 2 +- .../core/global_state/src/templates/index.rs | 2 +- examples/core/i18n/src/templates/about.rs | 2 +- examples/core/i18n/src/templates/index.rs | 2 +- examples/core/i18n/src/templates/post.rs | 2 +- .../core/idb_freezing/src/templates/about.rs | 2 +- .../core/idb_freezing/src/templates/index.rs | 2 +- examples/core/plugins/src/templates/about.rs | 2 +- examples/core/plugins/src/templates/index.rs | 2 +- .../core/router_state/src/templates/about.rs | 2 +- .../core/router_state/src/templates/index.rs | 2 +- examples/core/rx_state/src/templates/about.rs | 2 +- examples/core/rx_state/src/templates/index.rs | 2 +- .../core/set_headers/src/templates/index.rs | 2 +- .../src/templates/amalgamation.rs | 2 +- .../src/templates/build_paths.rs | 2 +- .../src/templates/build_state.rs | 2 +- .../src/templates/incremental_generation.rs | 2 +- .../src/templates/request_state.rs | 2 +- .../src/templates/revalidation.rs | 2 +- ...revalidation_and_incremental_generation.rs | 2 +- .../static_content/src/templates/index.rs | 2 +- .../demos/fetching/src/templates/index.rs | 2 +- packages/perseus-macro/src/template_rx.rs | 39 ++++++------------- 29 files changed, 40 insertions(+), 55 deletions(-) diff --git a/examples/.base/src/templates/index.rs b/examples/.base/src/templates/index.rs index 34faa5c796..220269e531 100644 --- a/examples/.base/src/templates/index.rs +++ b/examples/.base/src/templates/index.rs @@ -1,7 +1,7 @@ use perseus::{Html, Template}; use sycamore::prelude::{view, SsrNode, View}; -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page() -> View { view! { p { "Hello World!" } diff --git a/examples/core/basic/src/templates/about.rs b/examples/core/basic/src/templates/about.rs index d38da83655..9ee63b1800 100644 --- a/examples/core/basic/src/templates/about.rs +++ b/examples/core/basic/src/templates/about.rs @@ -1,7 +1,7 @@ use perseus::Template; use sycamore::prelude::{view, Html, SsrNode, View}; -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page() -> View { view! { p { "About." } diff --git a/examples/core/basic/src/templates/index.rs b/examples/core/basic/src/templates/index.rs index 11c0ee6b6d..3f89967718 100644 --- a/examples/core/basic/src/templates/index.rs +++ b/examples/core/basic/src/templates/index.rs @@ -6,7 +6,7 @@ pub struct IndexPageState { pub greeting: String, } -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page(state: IndexPageStateRx) -> View { view! { p { (state.greeting.get()) } diff --git a/examples/core/freezing_and_thawing/src/templates/about.rs b/examples/core/freezing_and_thawing/src/templates/about.rs index 500ca0af37..4619fa8998 100644 --- a/examples/core/freezing_and_thawing/src/templates/about.rs +++ b/examples/core/freezing_and_thawing/src/templates/about.rs @@ -4,7 +4,7 @@ use sycamore::prelude::*; use crate::global_state::AppStateRx; -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page(_: (), global_state: AppStateRx) -> View { let test = global_state.test; // This is not part of our data model, we do NOT want the frozen app synchronized as part of our page's state, it should be separate diff --git a/examples/core/freezing_and_thawing/src/templates/index.rs b/examples/core/freezing_and_thawing/src/templates/index.rs index d1f0a04963..f50bd98c8e 100644 --- a/examples/core/freezing_and_thawing/src/templates/index.rs +++ b/examples/core/freezing_and_thawing/src/templates/index.rs @@ -9,7 +9,7 @@ pub struct IndexProps { username: String, } -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page(state: IndexPropsRx, global_state: AppStateRx) -> View { let username = state.username; let username_2 = username.clone(); // This is necessary until Sycamore's new reactive primitives are released diff --git a/examples/core/global_state/src/templates/about.rs b/examples/core/global_state/src/templates/about.rs index 7b5617dbd4..3296048881 100644 --- a/examples/core/global_state/src/templates/about.rs +++ b/examples/core/global_state/src/templates/about.rs @@ -4,7 +4,7 @@ use sycamore::prelude::{view, SsrNode, View}; use crate::global_state::AppStateRx; // This template needs global state, but doesn't have any state of its own, so the first argument is the unit type `()` (which the macro will detect) -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page(_: (), global_state: AppStateRx) -> View { let test = global_state.test; let test_2 = test.clone(); diff --git a/examples/core/global_state/src/templates/index.rs b/examples/core/global_state/src/templates/index.rs index 9feaec438a..73ac7f77eb 100644 --- a/examples/core/global_state/src/templates/index.rs +++ b/examples/core/global_state/src/templates/index.rs @@ -4,7 +4,7 @@ use sycamore::prelude::{view, SsrNode, View}; use crate::global_state::AppStateRx; // This template needs global state, but doesn't have any state of its own, so the first argument is the unit type `()` (which the macro will detect) -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn index_page(_: (), global_state: AppStateRx) -> View { let test = global_state.test; let test_2 = test.clone(); diff --git a/examples/core/i18n/src/templates/about.rs b/examples/core/i18n/src/templates/about.rs index 3d3d3b009b..7f1a480e1e 100644 --- a/examples/core/i18n/src/templates/about.rs +++ b/examples/core/i18n/src/templates/about.rs @@ -1,7 +1,7 @@ use perseus::{t, Template}; use sycamore::prelude::{view, Html, View}; -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page() -> View { view! { p { (t!("about")) } diff --git a/examples/core/i18n/src/templates/index.rs b/examples/core/i18n/src/templates/index.rs index b7fe5fe2ab..1c2e32f0bb 100644 --- a/examples/core/i18n/src/templates/index.rs +++ b/examples/core/i18n/src/templates/index.rs @@ -1,7 +1,7 @@ use perseus::{link, t, Template}; use sycamore::prelude::{view, Html, View}; -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page() -> View { let username = "User"; view! { diff --git a/examples/core/i18n/src/templates/post.rs b/examples/core/i18n/src/templates/post.rs index 7a871824c4..e4dc3097f3 100644 --- a/examples/core/i18n/src/templates/post.rs +++ b/examples/core/i18n/src/templates/post.rs @@ -7,7 +7,7 @@ pub struct PostPageState { content: String, } -#[perseus::template_rx(PostPage)] +#[perseus::template_rx] pub fn post_page(props: PostPageStateRx) -> View { let title = props.title; let content = props.content; diff --git a/examples/core/idb_freezing/src/templates/about.rs b/examples/core/idb_freezing/src/templates/about.rs index 2abea3fc9f..0d08950c28 100644 --- a/examples/core/idb_freezing/src/templates/about.rs +++ b/examples/core/idb_freezing/src/templates/about.rs @@ -4,7 +4,7 @@ use sycamore::prelude::*; use crate::global_state::AppStateRx; -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page(_: (), global_state: AppStateRx) -> View { let test = global_state.test; // This is not part of our data model diff --git a/examples/core/idb_freezing/src/templates/index.rs b/examples/core/idb_freezing/src/templates/index.rs index 616721777d..84e17434bf 100644 --- a/examples/core/idb_freezing/src/templates/index.rs +++ b/examples/core/idb_freezing/src/templates/index.rs @@ -9,7 +9,7 @@ pub struct IndexProps { username: String, } -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page(state: IndexPropsRx, global_state: AppStateRx) -> View { let username = state.username; let username_2 = username.clone(); // This is necessary until Sycamore's new reactive primitives are released diff --git a/examples/core/plugins/src/templates/about.rs b/examples/core/plugins/src/templates/about.rs index f972e6cc4b..c598f58859 100644 --- a/examples/core/plugins/src/templates/about.rs +++ b/examples/core/plugins/src/templates/about.rs @@ -2,7 +2,7 @@ use perseus::Template; use sycamore::prelude::{view, Html, SsrNode, View}; // This page will actually be replaced entirely by a plugin! -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page() -> View { view! { p { "About." } diff --git a/examples/core/plugins/src/templates/index.rs b/examples/core/plugins/src/templates/index.rs index b980766440..528b52fda6 100644 --- a/examples/core/plugins/src/templates/index.rs +++ b/examples/core/plugins/src/templates/index.rs @@ -1,7 +1,7 @@ use perseus::{Html, Template}; use sycamore::prelude::{view, SsrNode, View}; -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page() -> View { view! { p { "Hello World!" } diff --git a/examples/core/router_state/src/templates/about.rs b/examples/core/router_state/src/templates/about.rs index 0663742c98..148c60d112 100644 --- a/examples/core/router_state/src/templates/about.rs +++ b/examples/core/router_state/src/templates/about.rs @@ -1,7 +1,7 @@ use perseus::{Html, Template}; use sycamore::prelude::{view, SsrNode, View}; -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page() -> View { view! { p { "Hello World!" } diff --git a/examples/core/router_state/src/templates/index.rs b/examples/core/router_state/src/templates/index.rs index a623cc6af0..72e805cb2f 100644 --- a/examples/core/router_state/src/templates/index.rs +++ b/examples/core/router_state/src/templates/index.rs @@ -1,7 +1,7 @@ use perseus::{templates::RouterLoadState, Html, Template}; use sycamore::prelude::{cloned, create_memo, view, View}; -#[perseus::template_rx(RouterStatePage)] +#[perseus::template_rx] pub fn router_state_page() -> View { let load_state = perseus::get_render_ctx!().router.get_load_state(); // This uses Sycamore's `create_memo` to create a state that will update whenever the router state changes diff --git a/examples/core/rx_state/src/templates/about.rs b/examples/core/rx_state/src/templates/about.rs index e5e8afbcf5..23d2a41204 100644 --- a/examples/core/rx_state/src/templates/about.rs +++ b/examples/core/rx_state/src/templates/about.rs @@ -6,7 +6,7 @@ use sycamore::view::View; // WARNING: Accessing the page state store manually as this template does is NOT recommended, and is done for demonstration purposes only! In reality, you should use global state for anything that // you need to share between pages. -#[perseus::template_rx(AboutPage)] +#[perseus::template_rx] pub fn about_page() -> View { // Get the page state store manually // The index page is just an empty string diff --git a/examples/core/rx_state/src/templates/index.rs b/examples/core/rx_state/src/templates/index.rs index e9ca9336d1..f51345fd0b 100644 --- a/examples/core/rx_state/src/templates/index.rs +++ b/examples/core/rx_state/src/templates/index.rs @@ -7,7 +7,7 @@ pub struct IndexPageState { } // This macro will make our state reactive *and* store it in the page state store, which means it'll be the same even if we go to the about page and come back (as long as we're in the same session) -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page(state: IndexPageStateRx) -> View { let username = state.username; let username_2 = username.clone(); diff --git a/examples/core/set_headers/src/templates/index.rs b/examples/core/set_headers/src/templates/index.rs index 54905586ef..bf21cef0e5 100644 --- a/examples/core/set_headers/src/templates/index.rs +++ b/examples/core/set_headers/src/templates/index.rs @@ -9,7 +9,7 @@ struct PageState { greeting: String, } -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page(state: PageStateRx) -> View { view! { p { (state.greeting.get()) } diff --git a/examples/core/state_generation/src/templates/amalgamation.rs b/examples/core/state_generation/src/templates/amalgamation.rs index 3414802a58..3ffbeedeb5 100644 --- a/examples/core/state_generation/src/templates/amalgamation.rs +++ b/examples/core/state_generation/src/templates/amalgamation.rs @@ -6,7 +6,7 @@ pub struct PageState { pub message: String, } -#[perseus::template_rx(AmalgamationPage)] +#[perseus::template_rx] pub fn amalgamation_page(state: PageStateRx) -> View { view! { p { (format!("The message is: '{}'", state.message.get())) } diff --git a/examples/core/state_generation/src/templates/build_paths.rs b/examples/core/state_generation/src/templates/build_paths.rs index 3e367d1233..ec39a95ff1 100644 --- a/examples/core/state_generation/src/templates/build_paths.rs +++ b/examples/core/state_generation/src/templates/build_paths.rs @@ -7,7 +7,7 @@ pub struct PageState { content: String, } -#[perseus::template_rx(BuildPathsPage)] +#[perseus::template_rx] pub fn build_paths_page(state: PageStateRx) -> View { let title = state.title; let content = state.content; diff --git a/examples/core/state_generation/src/templates/build_state.rs b/examples/core/state_generation/src/templates/build_state.rs index f080ac57b1..935bb30fb4 100644 --- a/examples/core/state_generation/src/templates/build_state.rs +++ b/examples/core/state_generation/src/templates/build_state.rs @@ -6,7 +6,7 @@ pub struct PageState { pub greeting: String, } -#[perseus::template_rx(BuildStatePage)] +#[perseus::template_rx] pub fn build_state_page(state: PageStateRx) -> View { view! { p { (state.greeting.get()) } diff --git a/examples/core/state_generation/src/templates/incremental_generation.rs b/examples/core/state_generation/src/templates/incremental_generation.rs index 65c4cad1ee..7179ad1a3b 100644 --- a/examples/core/state_generation/src/templates/incremental_generation.rs +++ b/examples/core/state_generation/src/templates/incremental_generation.rs @@ -9,7 +9,7 @@ pub struct PageState { content: String, } -#[perseus::template_rx(IncrementalGenerationPage)] +#[perseus::template_rx] pub fn incremental_generation_page(state: PageStateRx) -> View { let title = state.title; let content = state.content; diff --git a/examples/core/state_generation/src/templates/request_state.rs b/examples/core/state_generation/src/templates/request_state.rs index 48f2b477cd..4ba370430b 100644 --- a/examples/core/state_generation/src/templates/request_state.rs +++ b/examples/core/state_generation/src/templates/request_state.rs @@ -6,7 +6,7 @@ pub struct PageState { ip: String, } -#[perseus::template_rx(RequestStatePage)] +#[perseus::template_rx] pub fn request_state_page(state: PageStateRx) -> View { view! { p { diff --git a/examples/core/state_generation/src/templates/revalidation.rs b/examples/core/state_generation/src/templates/revalidation.rs index c973df9720..6852b0d13f 100644 --- a/examples/core/state_generation/src/templates/revalidation.rs +++ b/examples/core/state_generation/src/templates/revalidation.rs @@ -6,7 +6,7 @@ pub struct PageState { pub time: String, } -#[perseus::template_rx(RevalidationPage)] +#[perseus::template_rx] pub fn revalidation_page(state: PageStateRx) -> View { view! { p { (format!("The time when this page was last rendered was '{}'.", state.time.get())) } diff --git a/examples/core/state_generation/src/templates/revalidation_and_incremental_generation.rs b/examples/core/state_generation/src/templates/revalidation_and_incremental_generation.rs index 752610ff9e..5d53a7c350 100644 --- a/examples/core/state_generation/src/templates/revalidation_and_incremental_generation.rs +++ b/examples/core/state_generation/src/templates/revalidation_and_incremental_generation.rs @@ -9,7 +9,7 @@ pub struct PageState { pub time: String, } -#[perseus::template_rx(RevalidationPage)] +#[perseus::template_rx] pub fn revalidation_and_incremental_generation_page(state: PageStateRx) -> View { view! { p { (format!("The time when this page was last rendered was '{}'.", state.time.get())) } diff --git a/examples/core/static_content/src/templates/index.rs b/examples/core/static_content/src/templates/index.rs index 34faa5c796..220269e531 100644 --- a/examples/core/static_content/src/templates/index.rs +++ b/examples/core/static_content/src/templates/index.rs @@ -1,7 +1,7 @@ use perseus::{Html, Template}; use sycamore::prelude::{view, SsrNode, View}; -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page() -> View { view! { p { "Hello World!" } diff --git a/examples/demos/fetching/src/templates/index.rs b/examples/demos/fetching/src/templates/index.rs index 69507d720b..3ec63e90f7 100644 --- a/examples/demos/fetching/src/templates/index.rs +++ b/examples/demos/fetching/src/templates/index.rs @@ -7,7 +7,7 @@ pub struct IndexPageState { browser_ip: Option, } -#[perseus::template_rx(IndexPage)] +#[perseus::template_rx] pub fn index_page( IndexPageStateRx { server_ip, diff --git a/packages/perseus-macro/src/template_rx.rs b/packages/perseus-macro/src/template_rx.rs index fa9984705c..eacb315e82 100644 --- a/packages/perseus-macro/src/template_rx.rs +++ b/packages/perseus-macro/src/template_rx.rs @@ -173,26 +173,11 @@ pub fn template_impl(input: TemplateFn, attr_args: AttributeArgs) -> TokenStream } = input; // We want either one or two arguments - if attr_args.is_empty() || attr_args.len() > 2 { - return quote!(compile_error!( - "this macro takes either one or two arguments" - )); + if attr_args.len() > 1 { + return quote!(compile_error!("this macro takes one optional argument")); } - // This must always be provided - let component_name = match &attr_args[0] { - NestedMeta::Meta(meta) if meta.path().get_ident().is_some() => { - meta.path().get_ident().unwrap() - } - nested_meta => { - return syn::Error::new_spanned( - nested_meta, - "first argument must be a component identifier", - ) - .to_compile_error() - } - }; - // But this is optional (we'll use `G` as the default if it's not provided) - let type_param = match &attr_args.get(1) { + // This is optional (we'll use `G` as the default if it's not provided) + let type_param = match &attr_args.get(0) { Some(NestedMeta::Meta(meta)) if meta.path().get_ident().is_some() => { meta.path().get_ident().unwrap().clone() } @@ -254,7 +239,7 @@ pub fn template_impl(input: TemplateFn, attr_args: AttributeArgs) -> TokenStream // The user's function // We know this won't be async because Sycamore doesn't allow that #(#attrs)* - #[::sycamore::component(#component_name<#type_param>)] + #[::sycamore::component(PerseusPage<#type_param>)] fn #name#generics(#state_arg) -> #return_type { let #global_state_arg_pat: #global_state_rx = { let global_state = ::perseus::get_render_ctx!().global_state.0; @@ -266,7 +251,7 @@ pub fn template_impl(input: TemplateFn, attr_args: AttributeArgs) -> TokenStream #block } ::sycamore::prelude::view! { - #component_name(()) + PerseusPage(()) } } }, @@ -293,7 +278,7 @@ pub fn template_impl(input: TemplateFn, attr_args: AttributeArgs) -> TokenStream // The user's function // We know this won't be async because Sycamore doesn't allow that #(#attrs)* - #[::sycamore::component(#component_name<#type_param>)] + #[::sycamore::component(PerseusPage<#type_param>)] fn #name#generics(#state_arg) -> #return_type { let #global_state_arg_pat: #global_state_rx = { let global_state = ::perseus::get_render_ctx!().global_state.0; @@ -305,7 +290,7 @@ pub fn template_impl(input: TemplateFn, attr_args: AttributeArgs) -> TokenStream #block } ::sycamore::prelude::view! { - #component_name( + PerseusPage( { // Check if properties of the reactive type are already in the page state store // If they are, we'll use them (so state persists for templates across the whole app) @@ -348,12 +333,12 @@ pub fn template_impl(input: TemplateFn, attr_args: AttributeArgs) -> TokenStream // The user's function, with Sycamore component annotations and the like preserved // We know this won't be async because Sycamore doesn't allow that #(#attrs)* - #[::sycamore::component(#component_name<#type_param>)] + #[::sycamore::component(PerseusPage<#type_param>)] fn #name#generics(#arg) -> #return_type { #block } ::sycamore::prelude::view! { - #component_name( + PerseusPage( { // Check if properties of the reactive type are already in the page state store // If they are, we'll use them (so state persists for templates across the whole app) @@ -388,12 +373,12 @@ pub fn template_impl(input: TemplateFn, attr_args: AttributeArgs) -> TokenStream // The user's function, with Sycamore component annotations and the like preserved // We know this won't be async because Sycamore doesn't allow that #(#attrs)* - #[::sycamore::component(#component_name<#type_param>)] + #[::sycamore::component(PerseusPage<#type_param>)] fn #name#generics() -> #return_type { #block } ::sycamore::prelude::view! { - #component_name() + PerseusPage() } } }