projectfluent / fluent-rs

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

Make FluentMessage::attributes() return ExactSizeIterator #263

Open juliancoffee opened 2 years ago

juliancoffee commented 2 years ago

It may be an unusual way of using attributes, but we plan to use them to implement message variation, for example, for NPCs speech in the game.

npc-speech-adventurous =
    .1 = I hope to make my own glider someday.
    .2 = I'd like to go spelunking in a cave when I'm stronger.

And we would like to choose a random message. To do that we have multiple options. 1) Collect everything into Vec, which seems like redundancy when attributes are already Vec internally. 2) Expose the vector directly, which might harm incapsulation a bit 3) Make .attributes() return ExactSizeIterator, so that we can get the length of it, and then using .skip() taking needed element.

juliancoffee commented 2 years ago

@zbraniecki do you foresee any problems with this?

zbraniecki commented 2 years ago

It may be a case of an explicit antipattern in Fluent - https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers#prefer-separate-messages-over-variants-for-ui-logic

If those are actually variants of the same message, as in same message but varied by tone etc. then maybe it's ok. But generally, I'd advise you to create them as separate messages and store a Vec of message ids in your code to select from.

juliancoffee commented 2 years ago

Well, reading this link, I would say "yes" to both.

Use variants only if the default variant makes sense for all possible values of the selector. When using variants, keep in mind that other languages may collapse them into a single variant due to their grammar.

Otherwise, we wouldn't have them random :)

juliancoffee commented 2 years ago

Also to add to this, having it random makes it possible to have a different number of variants in different languages.