mondeja / leptos-fluent

Internationalization framework for Leptos using Fluent
https://mondeja.github.io/leptos-fluent/
MIT License
32 stars 9 forks source link

[Bug] "if" compilation error for leptos_fluent macro #212

Closed SleeplessOne1917 closed 1 month ago

SleeplessOne1917 commented 1 month ago

I recently tried building my project and got this compilation error:

error: missing condition for `if` expression
  --> src/lib.rs:60:5
   |
50 |   leptos_fluent! {{
   |   - if this block is the condition of the `if` expression, then it must be followed by another block
...
60 |   }};
   |     ^ expected condition here
   |
   = note: this error originates in the macro `leptos_fluent` (in Nightly builds, run with -Z macro-backtrace for more info)

At first I thought it was an error with leptos-fluent v0.1.14. However, I tried rolling back to v0.1.13 and v0.1.12 and still got the same issue.

My suspicion is that this is related to the recently released new versions of web-sys, wasm-bindgen, and js-sys. This update also prompted some other crates in the leptos ecosystem to release new versions compatible with these, such as leptos's 0.6.14 update and leptos-use's 0.12.0 update. It could be something else, but considering I'm running into this issue even with older versions of leptos-fluent and I ran into this issue very shortly after the web-sys et al updates, this is my best guess.

mondeja commented 1 month ago

My suspicion is that this is related to the recently released new versions of web-sys, wasm-bindgen, and js-sys.

I don't think so. Seems like if an if in the leptos_fluent! macro would being expanded to an empty expression. The code is plenty of:

quote! {
    if #expr {
        #effect_quote
    }
}

If expr is empty for some reason that would be the expected error, but we could add a check to stop showing that strange message.

Would you mind to paste your leptos_fluent! invocation?

SleeplessOne1917 commented 1 month ago
  leptos_fluent! {{
    translations: [TRANSLATIONS],
    locales: "./locales",
    check_translations: "./src/**/*.rs",
    sync_html_tag_lang: true,
    initial_language_from_accept_language_header: true,
    cookie_attrs: "SameSite=Strict; Secure;",
    initial_language_from_cookie: true,
    set_language_to_cookie: true,
    initial_language_from_navigator: true
  }};
mondeja commented 1 month ago

🤔 Really weird, I can't reproduce it with latest wasm-bindgen, web-sys and js-sys.

mondeja commented 1 month ago

If you're able to fork, uncomment the following line and paste the result we can check what is causing it.

https://github.com/mondeja/leptos-fluent/blob/834e45134bd560af802837307684d370ea4f48b6/leptos-fluent-macros/src/lib.rs#L2238

mondeja commented 1 month ago

Not sure if #213 could have fixed this problem (only related to code introduced in v0.1.14). Try the master branch and I'll release a patch if so.

SleeplessOne1917 commented 1 month ago

I tried using the main branch and am still having the issue. I uncommented the line you suggested and this is the output:

{
    const LANGUAGES : [& :: leptos_fluent :: Language; 1usize] =
    [&::leptos_fluent::Language{
        id: ::fluent_templates::loader::langid!("en"),name: "English",dir:
        &::leptos_fluent::WritingDirection::Ltr,flag: None
    }]; let mut lang : Option < & 'static :: leptos_fluent :: Language > =
    None; if lang.is_none()
    {
        if let Some(req) = :: leptos :: use_context :: < :: actix_web ::
        HttpRequest > ()
        {
            let maybe_cookie =
            req.cookie("lf-lang").and_then(| cookie |
            Some(cookie.value().to_string())); if let Some(cookie) =
            maybe_cookie
            {
                if let Some(l) = :: leptos_fluent :: l(& cookie, & LANGUAGES)
                { lang = Some(l); ; }
            }
        };
    } if lang.is_none()
    {
        if let Some(req) = :: leptos :: use_context :: < :: actix_web ::
        HttpRequest > ()
        {
            let maybe_header =
            req.headers().get(:: actix_web :: http :: header ::
            ACCEPT_LANGUAGE).and_then(| header | header.to_str().ok()); if let
            Some(header) = maybe_header
            {
                let langs = :: leptos_fluent :: http_header :: parse(header);
                for l in langs
                {
                    if let Some(l) = :: leptos_fluent :: l(& l, & LANGUAGES)
                    { lang = Some(l); break; }
                }
            }
        }
    }; let initial_lang = if let Some(l) = lang { l } else { LANGUAGES [0] };
    let mut i18n = :: leptos_fluent :: I18n
    {
        language : :: leptos :: create_rw_signal(initial_lang), languages : &
        LANGUAGES, translations : :: leptos :: Signal ::
        derive(||
        {
            let mut all_loaders = Vec :: new();
            all_loaders.extend([& TRANSLATIONS]); all_loaders
        }),
    }; :: leptos :: provide_context :: < :: leptos_fluent :: I18n > (i18n);
    let l = :: leptos_fluent :: i18n().language.get(); let (class, _, dir) =
    {
        :: leptos_meta :: provide_meta_context(); let html_tag_as_string = ::
        leptos_meta :: use_head().html.as_string().unwrap_or("".to_string());
        let mut class : Option < :: leptos :: TextProp > = None; let mut lang
        : Option < :: leptos :: TextProp > = None; let mut dir : Option < ::
        leptos :: TextProp > = None; for attr in html_tag_as_string.split(' ')
        {
            let mut parts = attr.split('='); let key =
            parts.next().unwrap_or(""); let value =
            parts.next().unwrap_or(""); if key == "class"
            { class = Some(value.trim_matches('"').to_string().into()); } else
            if key == "lang"
            { lang = Some(value.trim_matches('"').to_string().into()); } else
            if key == "dir"
            { dir = Some(value.trim_matches('"').to_string().into()); }
        } (class, lang, dir)
    }; :: leptos_meta ::
    Html(:: leptos_meta :: HtmlProps
    {
        lang : Some(l.id.to_string().into()), dir : if
        { Some(l.dir.as_str().into()) } else { dir }, class, attributes : Vec
        :: new(),
    });
    {
        let sen0 =
        include_bytes!("/home/insomnia/Projects/lemmy-stuff/lemmy-ui-leptos/./locales/en/main.ftl");
    }; ; i18n
}
mondeja commented 1 month ago

Thank you, I'm able to reproduce it. The version v0.1.15 with a fix for this bug will be released in a few minutes.

SleeplessOne1917 commented 1 month ago

I'll test the new version in my project once I get the chance.

SleeplessOne1917 commented 1 month ago

I just tested the change and the build worked!