While I can do what I want with an explicit match statement, I'd like to figure out how to make the following code work. The problem is that one of the steps in the closure returns a Result. (I'm using Failure if that makes a difference.)
I assume you mean or_insert_with in your examples?
I don't think there's an API to help here, and a match is currently your best bet.
If we were to add something to Entry, I imagine it would be based on the Try trait. I'm not sure how to write that though, because we'd need the FnOnce closure to return a Try type with the V value, but then somehow transform that to a similar Try type with &mut V to return. Maybe that just has to return Result instead.
Hmm, good point that this really wants to be able to accept a type constructor, not a concrete type. Best I can come up with right now is something like
pub fn or_insert_with<F: FnOnce() -> V, T: Try<Ok=V>, R: Try<Ok=&mut V>>(self, default: F) -> &'a mut V where R::Error: From<T::Error>
But I doubt that's the signature anyone actually wants.
I might be misinterpreting what you mean by "eat the error" here, but this strikes me as (part of) the source of your conflict. Fundamentally, there are three things you can do in the closure with errors:
unwrap and potentially panic
deal with them and hide (eat) them so you return a bare Foo, perhaps in some way that implictly encodes a masked error, like a default value
pass them through and deal with them later (return the Result and store that in the hashmap).
Regardless of the syntax of how you extract the Foo, it seems to me you're perhaps still undecided about your strategy and requirement here.
Footnote: I've found myselt sometimes doing a mapping from Result to Option, but that's just a variant of 2 that still leaves you to do the work of 3. In those cases it makes sense because they're truly optional values (like config items from a config file that might not exist, etc).
I agree it's not terrible, but I'd rather not give people NoneErrors in Results if I can help it, so I'd probably rather just force both to be Result until we get enough GAT support to make the API we obviously want. We can always name it or_insert_with_result or something for now, if there's concern it couldn't be compatibly expanded to be generic later.