projectfluent / fluent-rs

Rust implementation of Project Fluent
https://projectfluent.org
Apache License 2.0
1.09k stars 97 forks source link

Why using reference against move in FluentBundle::add_resource()? #98

Closed renyuneyun closed 5 years ago

renyuneyun commented 5 years ago

TL;DR: Why does the FluentBundle::add_resource() function takes a reference of FluentResource, rather than directly taking the value/ownership (move?)? The FluentResource is useless outside of FluentBundle, as far as I'm concerned.


I'm working on a fluent-rs wrapper (as a part of something else) which takes care of all the fluent loading and FluentBundle object constructing, because of #64 . Because the project uses Rocket and the fluent part is used in/as a fairing, everything here (FluentBundle & FluentResource) should live inside the fairing or being static (which is not possible(?)). It makes a lot of sense if FluentBundle can take ownership of all its FluentResources and make the fairing (struct) only store the FluentBundle. So why doesn't FluentBundle::add_resource() have the value as the parameter? The only reason I can think of is to have the same FluentResource passed to two FluentBundles. But this doesn't make sense because FluentBundle::format() can return None and the programmer can fallback to another FluentBundle.

(Since I still don't have much experience in rust, I never find a way to make the FluentResource live in the fairing struct with FluentBundle (in the same struct) pointing to it (neither do I know if this is possible at all)... It would be much easier to new people to use fluent-rs if this investigation can be avoided.)

zbraniecki commented 5 years ago

The FluentResource is useless outside of FluentBundle, as far as I'm concerned.

Think of FluentResource like any other resource or asset. It can be reused in multiple places, and we only want to load/parse it once.

For example in Firefox we may have the following (simplified scenario) assets: ["brand.ftl", "menu.ftl", "preferences.ftl"] and load it in two combinations: ["brand.ftl", "preferences.ftl"] and ["brand.ftl", "menu.ftl"] depending on needs.

This of course scales with permutations.

Our strategy is to create some resource manager that loads the resources and stores references to them, allowing to create "cheap" FluentBundles to operate on them.

But this doesn't make sense because FluentBundle::format() can return None and the programmer can fallback to another FluentBundle.

That's not about fallbacking. Fluent allows to reference messages and terms within the same bundle allowing the above scenario to have key = { brand-name } in preferences.ftl where brand-name comes from brand.ftl.

You can mock a resource manager just like we do in the examples/simple-app.rs or you can use some ResourceManager for it. For example I have a branch resmgr which will add it and it's part of #88.

Let me know if that does answer your question sufficiently!

zbraniecki commented 5 years ago

@renyuneyun - can you confirm if this answers your question? I'd like to triage this issue as either actionable or to be closed. Thank you!

zbraniecki commented 5 years ago

Closing due to lack of response from the reporter.

renyuneyun commented 5 years ago

Ah, yes. It does answer my question! Sorry I didn't see the notification...