One approach to solving item 1 is to think about the default as not being a separate key to the HashMap, but being a part of the value for that key, which allows you to model this a little more explicitly:
The article makes the 'default' key with push_str("-default"), and given that, your approach should work. But i think that's a placeholder, and a bit of an odd one - i think it's more likely to see something like (pardon my rusty Rust) k = if let Some((head, _)) = k.split_once("_") { head.to_owned() } else { k } - so for example a lookup for "es_MX" will default to "es". I don't think your approach helps there.
Yeah, true. But that (assuming you're saying give me es_MX if it exists otherwise es) has a similar possible solution. Model your Language and variants hierarchically rather than flat. So languages.get("es_MX") becomes
let language = languages.get_language("es");
let variant = language.get_variant("MX");
There's probably other more general ideas where this can't be fixed (but there's some internal changes to the rules mentioned in other parts of this thread somewhere on (here/reddit/lobsters).
Isn’t it actually a Standard ML and C/C++ hybrid? The window dressing is C/C++ sure, but the lack of statements, semicolons, the presence of enums, etc are quite reminiscent of SML.
I think it’s because the typelevel expressions (e.g. trait constraints, lifetimes, impl<T> for Trait<U>), ubiquitous refs, and other type annotations have a much more complicated and explicit grammar than what we tend to see in other languages.
It is really not that much like C++ syntax in that respect nor is it cleaner. In other respects, it is more like a cleaner C++, but this is an aspect that is in fact more complicated, and harder to read and write.
Rust people need to be more honest about what Rust is really like.