From 15946c61365dbdc6844a8af49e73ac0e03e540ce Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Mon, 25 Dec 2023 14:30:31 -0500 Subject: [PATCH 1/4] fix: emit original token stream when there are syntax errors in `#[component]` or `#[island]` function signature (closes #2133) (#2134) --- leptos_macro/src/lib.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/leptos_macro/src/lib.rs b/leptos_macro/src/lib.rs index 25fc33dcf7..b9c6ceead2 100644 --- a/leptos_macro/src/lib.rs +++ b/leptos_macro/src/lib.rs @@ -603,10 +603,12 @@ pub fn component(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream { false }; - let mut dummy = syn::parse::(s.clone()); + let Ok(mut dummy) = syn::parse::(s.clone()) else { + return s; + }; let parse_result = syn::parse::(s); - if let (Ok(ref mut unexpanded), Ok(model)) = (&mut dummy, parse_result) { + if let (ref mut unexpanded, Ok(model)) = (&mut dummy, parse_result) { let expanded = model.is_transparent(is_transparent).into_token_stream(); unexpanded.sig.ident = unmodified_fn_name_from_fn_name(&unexpanded.sig.ident); @@ -616,15 +618,13 @@ pub fn component(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream { #[allow(non_snake_case, dead_code, clippy::too_many_arguments)] #unexpanded } - } else if let Ok(mut dummy) = dummy { + } else { dummy.sig.ident = unmodified_fn_name_from_fn_name(&dummy.sig.ident); quote! { #[doc(hidden)] #[allow(non_snake_case, dead_code, clippy::too_many_arguments)] #dummy } - } else { - quote! {} } .into() } @@ -703,10 +703,12 @@ pub fn component(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream { #[proc_macro_error::proc_macro_error] #[proc_macro_attribute] pub fn island(_args: proc_macro::TokenStream, s: TokenStream) -> TokenStream { - let mut dummy = syn::parse::(s.clone()); + let Ok(mut dummy) = syn::parse::(s.clone()) else { + return s; + }; let parse_result = syn::parse::(s); - if let (Ok(ref mut unexpanded), Ok(model)) = (&mut dummy, parse_result) { + if let (ref mut unexpanded, Ok(model)) = (&mut dummy, parse_result) { let expanded = model.is_island().into_token_stream(); if !matches!(unexpanded.vis, Visibility::Public(_)) { unexpanded.vis = Visibility::Public(Pub { @@ -721,15 +723,13 @@ pub fn island(_args: proc_macro::TokenStream, s: TokenStream) -> TokenStream { #[allow(non_snake_case, dead_code, clippy::too_many_arguments)] #unexpanded } - } else if let Ok(mut dummy) = dummy { + } else { dummy.sig.ident = unmodified_fn_name_from_fn_name(&dummy.sig.ident); quote! { #[doc(hidden)] #[allow(non_snake_case, dead_code, clippy::too_many_arguments)] #dummy } - } else { - quote! {} } .into() } From b4a9db51be23b97111054a54f817ad844b2b809c Mon Sep 17 00:00:00 2001 From: JackSpagnoli Date: Fri, 29 Dec 2023 01:07:49 +0000 Subject: [PATCH 2/4] chore: fix broken tailwind example repo link (#2138) --- leptos/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/leptos/src/lib.rs b/leptos/src/lib.rs index 02d98908b7..0d208a21a4 100644 --- a/leptos/src/lib.rs +++ b/leptos/src/lib.rs @@ -57,8 +57,8 @@ //! [`todo_app_sqlite_axum`](https://github.com/leptos-rs/leptos/tree/main/examples/todo_app_sqlite_axum), and //! [`todo_app_sqlite_viz`](https://github.com/leptos-rs/leptos/tree/main/examples/todo_app_sqlite_viz) //! show how to build a full-stack app using server functions and database connections. -//! - [`tailwind`](https://github.com/leptos-rs/leptos/tree/main/examples/tailwind) shows how to integrate -//! TailwindCSS with `cargo-leptos`. +//! - [`tailwind`](https://github.com/leptos-rs/leptos/tree/main/examples/tailwind_csr) shows how to integrate +//! TailwindCSS with `trunk` for CSR. //! //! Details on how to run each example can be found in its README. //! From da533ad4e0f8908b81a51c2203a019fedd810837 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 30 Dec 2023 08:14:23 -0500 Subject: [PATCH 3/4] chore: clarify `cargo-make` and examples (see #2141) (#2150) --- examples/README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/examples/README.md b/examples/README.md index ed307bd009..1bb63e07be 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,23 +4,15 @@ The examples in this directory are all built and tested against the current `main` branch. -To the extent that new features have been released or breaking changes have been made since the previous release, the examples are compatible with the `main` branch but not the current release. +To the extent that new features have been released or breaking changes have been made since the previous release, the examples are compatible with the `main` branch and not the current release. -To see the examples as they were at the time of the `0.5.0` release, [click here](https://github.com/leptos-rs/leptos/tree/v0.5.0/examples). - -## Cargo Make - -[Cargo Make](https://sagiegurari.github.io/cargo-make/) is used to build, test, and run examples. +## Getting Started -Here are the highlights. +The simplest way to get started with any example is to use the “quick start” command found in the README for each example. Most of the examples use either [`trunk`](https://trunkrs.dev/) (a simple build system and dev server for client-side-rendered apps) or [`cargo-leptos`](https://github.com/leptos-rs/cargo-leptos) (a build system for server-rendered and client-hydrated apps). -- Extendable custom task files are located in the [cargo-make](./cargo-make/) directory -- Running a task will automatically install `cargo` dependencies -- Each `Makefile.toml` file must extend the [cargo-make/main.toml](./cargo-make/main.toml) file -- [cargo-make](./cargo-make/) files that end in `*-test.toml` configure web testing strategies -- Run `cargo make test-report` to learn which examples have web tests +## Using Cargo Make -## Getting Started +You can also run any of the examples using [`cargo-make`](https://github.com/sagiegurari/cargo-make). Note that this is completely optional. We use it for CI, and it can be convenient for running the examples, but is not required. Follow these steps to get any example up and running. @@ -28,6 +20,15 @@ Follow these steps to get any example up and running. 2. Run `cargo make ci` to setup and test the example 3. Run `cargo make start` to run the example 4. Open the client URL in the console output ( or by default) +5. Run `cargo make stop` to end any processes started by `cargo make start`. + +Here are a few additional notes: + +- Extendable custom task files are located in the [cargo-make](./cargo-make/) directory +- Running a task will automatically install `cargo` dependencies +- Each `Makefile.toml` file must extend the [cargo-make/main.toml](./cargo-make/main.toml) file +- [cargo-make](./cargo-make/) files that end in `*-test.toml` configure web testing strategies +- Run `cargo make test-report` to learn which examples have web tests ## Prerequisites From 16cf3c4eafd660ab68a7a8dff1e06096f061ffea Mon Sep 17 00:00:00 2001 From: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com> Date: Sat, 30 Dec 2023 18:10:07 +0000 Subject: [PATCH 4/4] feat: make `IntoAttribute` more flexible for `Option` (#2130) --- .../src/macro_helpers/into_attribute.rs | 80 +------------------ leptos_dom/src/nonce.rs | 10 --- 2 files changed, 3 insertions(+), 87 deletions(-) diff --git a/leptos_dom/src/macro_helpers/into_attribute.rs b/leptos_dom/src/macro_helpers/into_attribute.rs index 18a8fa7c7e..18dc834291 100644 --- a/leptos_dom/src/macro_helpers/into_attribute.rs +++ b/leptos_dom/src/macro_helpers/into_attribute.rs @@ -138,15 +138,6 @@ macro_rules! impl_into_attr_boxed { }; } -impl IntoAttribute for Option { - #[inline(always)] - fn into_attribute(self) -> Attribute { - self.unwrap_or(Attribute::Option(None)) - } - - impl_into_attr_boxed! {} -} - impl IntoAttribute for String { #[inline(always)] fn into_attribute(self) -> Attribute { @@ -201,46 +192,10 @@ impl IntoAttribute for bool { impl_into_attr_boxed! {} } -impl IntoAttribute for Option { - #[inline(always)] - fn into_attribute(self) -> Attribute { - Attribute::Option(self.map(Oco::Owned)) - } - - impl_into_attr_boxed! {} -} - -impl IntoAttribute for Option<&'static str> { - #[inline(always)] - fn into_attribute(self) -> Attribute { - Attribute::Option(self.map(Oco::Borrowed)) - } - - impl_into_attr_boxed! {} -} - -impl IntoAttribute for Option> { +impl IntoAttribute for Option { #[inline(always)] fn into_attribute(self) -> Attribute { - Attribute::Option(self.map(Oco::Counted)) - } - - impl_into_attr_boxed! {} -} - -impl IntoAttribute for Option> { - #[inline(always)] - fn into_attribute(self) -> Attribute { - Attribute::Option(self.map(Oco::from)) - } - - impl_into_attr_boxed! {} -} - -impl IntoAttribute for Option> { - #[inline(always)] - fn into_attribute(self) -> Attribute { - Attribute::Option(self) + self.map_or(Attribute::Option(None), IntoAttribute::into_attribute) } impl_into_attr_boxed! {} @@ -310,17 +265,6 @@ macro_rules! attr_type { self.into_attribute() } } - - impl IntoAttribute for Option<$attr_type> { - fn into_attribute(self) -> Attribute { - Attribute::Option(self.map(|n| n.to_string().into())) - } - - #[inline] - fn into_attribute_boxed(self: Box) -> Attribute { - self.into_attribute() - } - } }; } @@ -341,24 +285,6 @@ macro_rules! attr_signal_type { }; } -macro_rules! attr_signal_type_optional { - ($signal_type:ty) => { - #[cfg(not(feature = "nightly"))] - impl IntoAttribute for $signal_type - where - T: Clone, - Option: IntoAttribute, - { - fn into_attribute(self) -> Attribute { - let modified_fn = Rc::new(move || self.get().into_attribute()); - Attribute::Fn(modified_fn) - } - - impl_into_attr_boxed! {} - } - }; -} - attr_type!(&String); attr_type!(usize); attr_type!(u8); @@ -381,7 +307,7 @@ attr_signal_type!(RwSignal); attr_signal_type!(Memo); attr_signal_type!(Signal); attr_signal_type!(MaybeSignal); -attr_signal_type_optional!(MaybeProp); +attr_signal_type!(MaybeProp); #[cfg(all(target_arch = "wasm32", feature = "web"))] #[doc(hidden)] diff --git a/leptos_dom/src/nonce.rs b/leptos_dom/src/nonce.rs index 1969b68de0..68b7c0dbe6 100644 --- a/leptos_dom/src/nonce.rs +++ b/leptos_dom/src/nonce.rs @@ -69,16 +69,6 @@ impl IntoAttribute for Nonce { } } -impl IntoAttribute for Option { - fn into_attribute(self) -> Attribute { - Attribute::Option(self.map(|n| n.0.into())) - } - - fn into_attribute_boxed(self: Box) -> Attribute { - Attribute::Option(self.map(|n| n.0.into())) - } -} - /// Accesses the nonce that has been generated during the current /// server response. This can be added to inline `