Fluent templates -- having a difficult type mismatch problem

I am using the (so far, terrific!) Fluent Templates crate. I'm using it with handlebars and I'm getting a doozy of a type mismatch build error that I can't quite grok.

Here's what I'm doing:

    let loader = ArcLoader::builder(
        "resources/locales",
        langid!("en-US")
    )
        .build()
        .unwrap();

    let mut handlebars = Handlebars::new();
    let helper = Box::new(FluentLoader::new(&loader));
    handlebars.register_helper("fluent", helper);

In theory, this should work. FluentLoader implements the Handlebars HelperDef trait.

However, I get this compilation error:

error[E0277]: expected a `std::ops::FnOnce<(&handlebars::render::Helper<'reg, 'rc>, &'reg handlebars::registry::Registry<'reg>, &'rc handlebars::context::Context, &mut handlebars::render::RenderContext<'reg, 'rc>, &mut dyn handlebars::output::Output)>` closure, found `fluent_templates::loader::FluentLoader<&fluent_templates::loader::arc_loader::ArcLoader>`

Flattened out a bit:

error[E0277]: expected a `std::ops::FnOnce<(
    &handlebars::render::Helper<'reg, 'rc>, 
    &'reg handlebars::registry::Registry<'reg>, 
    &'rc handlebars::context::Context, 
    &mut handlebars::render::RenderContext<'reg, 'rc>, 
    &mut dyn handlebars::output::Output
)>` closure, found `fluent_templates::loader::FluentLoader<&fluent_templates::loader::arc_loader::ArcLoader>`

I can see that that is the signature of the call method in the HelperDef trait, but I can't for the life of me figure out why the struct I'm passing to register_helper() doesn't fit the expected type.

It looks like the register_helper function wants is a boxed trait object : https://docs.rs/handlebars/3.1.0/handlebars/struct.Handlebars.html#method.register_helper

Your let helper=Box::new(...) line is creating a boxed raw instance instead. Either removing the intermediate variable helper or explicity identifying its type (let helper:Box<dyn Helperdef + Send + Sync>=...) should fix the problem.

Thank you -- interestingly, I get the same error with the construction of the helper object inline.

I tried specifying the type explicitly in the manner you describe, and... I now get the same error in that assignment. ¯\_(ツ)_/¯

61 |     let helper: Box<dyn HelperDef + Send + Sync> = Box::new(FluentLoader::new(&loader));
   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an 
`Fn<(&handlebars::render::Helper<'reg, 'rc>, &'reg handlebars::registry::Registry<'reg>, &'rc handlebars::context::Context, &mut handlebars::render::RenderContext<'reg, 'rc>, &mut dyn handlebars::output::Output)>` closure, found `fluent_templates::loader::FluentLoader<&fluent_templates::loader::arc_loader::ArcLoader>`

In case anyone else stumbles across this issue, the problem was that the Handlebars support is locked behind a feature in the fluent-templates crate. The fluent templates handlebars helper didn't exist in my project, because I didn't include that feature, so rustc was trying to match my call to the closest implementation of HelperDef it could, which was the one for passing a raw function as a helper.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.