leptos-rs / leptos

Build fast web applications with Rust.
https://leptos.dev
MIT License
16.43k stars 658 forks source link

`view!` macro panics when encountering an invalid character literal #2952

Open landaire opened 2 months ago

landaire commented 2 months ago

Describe the bug

An invalid character literal in view! causes the proc macro to fail an assertion and panic:

error: character literal may only contain one codepoint
  --> src/components/stats.rs:23:42
   |
23 |             import { initFlowbite } from 'flowbite'
   |                                          ^^^^^^^^^^
   |
help: if you meant to write a string literal, use double quotes
   |
23 |             import { initFlowbite } from "flowbite"
   |                                          ~        ~

error: proc macro panicked
  --> src/components/stats.rs:21:5
   |
21 | /     view! {
22 | |         <Script>
23 | |             import { initFlowbite } from 'flowbite'
...  |
41 | |         </button>
42 | |     }
   | |_____^
   |
   = help: message: assertion `left == right` failed
             left: 108
            right: 39

Leptos Dependencies

Please copy and paste the Leptos dependencies and features from your Cargo.toml.

For example:

leptos = { version = "0.6", features = ["nightly"] }
leptos_axum = { version = "0.6", optional = true }
leptos_meta = { version = "0.6", features = ["nightly"] }
leptos_router = { version = "0.6", features = ["nightly"] }

To Reproduce

The following causes the view! proc macro to panic:

use leptos::*;
use leptos_meta::*;
use leptos_router::*;
use server_fn::error::NoCustomError;

/// Renders the home page of your application.
#[component]
pub fn StatsPage() -> impl IntoView {
    provide_meta_context();
    // Creates a reactive value to update the button
    let (count, set_count) = create_signal(0u32);

    view! {
        <Script>
            'foo'
        </Script>
        <h2 class="p-6 text-4xl">"Welcome to Leptos with Tailwind"</h2>
        <p class="px-10 pb-10 text-left">"Tailwind will scan your Rust files for Tailwind class names and compile them into a CSS file."</p>
        <button
            class="bg-amber-600 hover:bg-sky-700 px-5 py-3 text-white rounded-lg"
            on:click=move |_| set_count.update(|count| *count += 1)
        >
            "Something's here | "
            {move || if count.get() == 0 {
                "Click me!".to_string()
            } else {
                count.get().to_string()
            }}
            " | Some more text"
        </button>
    }
}

Expected behavior

The proc macro should fail gracefully.

gbj commented 2 months ago

This is invalid Rust syntax of course, so can't ever be parsed by a proc macro, since proc macros need to consist of a stream of valid tokens. I can look into whether the panic comes from rstml or from leptos, but either way you should just use a regular Rust string here with the JavaScript inside it.

landaire commented 2 months ago

Yeah for what it's worth I realize that what I was doing is not valid, but I was surprised that I got what seemed to be a valid error (error: character literal may only contain one codepoint) then a panic. This isn't something that I see as a high-priority at all but might be a UX improvement.