I’m working on a crate called
fluent-locale which is meant to provide language negotiation capabilities.
I’m looking for advice from the community on how to design an API for this capability.
In the simplest form, language negotiation takes a list of language identifiers, filters and reorders them according to some criteria.
For example, it may look like this:
let available = ["en-US", "de-DE", "es-AR"]; let requested = ["de", "fr", "en"]; let supported = negotiate_languages(available, requested);
The list of
supported is coming from
available filtered out and reordered based on data from
The first issue is that since my functionality is really similar to
filter, I’m wondering if it should be some trait on Iterator, Array or Vec instead. In particular, I’d like to avoid cloning, but I’m not sure how to do it.
Second issue is that behind the scenes, I will not operate on strings. I’ll operate on structs called
unic-langid) which have
If my API accepts
&str, then I have to decide what to do if
TryFrom fails - in other words, if someone passes a list of locales, and one of the locales is not valid, I’ll need to decide how to handle that scenario within my API.
So it’s tempting to instead ask users to create lists of
LanguageIdentifier and then negotiate them against lists of other
It would be a bit less easy to work with, because in most cases, apps will receive lists of strings, either from the user, or from some settings. But the benefit of having the user decide how to handle incorrect strings, may make it worth it not to accept strings in my API. What do you think?
If I’m right, then the API could be a trait on
Vec<LanguageIdentifier>, and the user would do sth like:
let requested = req_strings.map(|s| LanguageIdentifier::try_from(s).unwrap()).collect(); let available = av_strings.map(|s| LanguageIdentifier::try_from(s).unwrap()).collect(); let supported = available.negotiate_against(requested);
Does it sound reasonable? What’s the idiomatic way to avoid cloning when not necessary? Should I consume
available? Should I operate on
&LanguageIdentifier and clone the reference to
supported and keep
Any ideas on how to design such API appreciated!
Hope my brainstorm questions make sense