I'm working on a wrapper around a sys crate and I'm having a little trouble with the ergonomics of a wrapped dictionary.
The sys crate implements its own symbol table (created from const char *) and uses those symbols as keys for dictionary access. I've wrapped the crate's Symbol with fallible TryInto implementations for String and &str and now I'm looking into wrapping the dictionary and stumbling with the ergonomics of the symbol creation.
Basically, I would really love to be able to do dict.insert(&"foo", 2); as well as let s = Symbol::new("bar"); dict.insert(&s, 2084); but as is I'm doing dict.insert("foo".try_into().unwrap(), 2); insert's key is a Into<Symbol>
Basically, my question is.. would it make sense to just make the conversion from &str infallible, panicking on error, in sake of ergonomics, or, does anyone else have any better solution?
I guess one option could be to make the wrapper's Dict use a new struct, DictKey(Symbol), for its key and then make infallible (panicking) conversions from &str, Symbol, etc to DictKey ?
thanks @sollyucko , great ideas there. impl TryInto<Symbol> could be it! Most of these methods return Result already so I could just add something like KeyError ..
Re calling code dealing with an error other than panicking, I'm not sure, this is library code for implementing a plugin, I hope that people implementing plugins don't panic but I also don't expect that they use keys that should cause a panic in the first place.
If .insert() already yields a Result, then for all means shuffle the error handling of key conversion in there as well; but do note that you should be able to feature unfallible conversions if they keys are CStr literals or CStrings, at which point your question becomes is it possible to have ergonomic creation of those.
To that question, there are a bunch of crates out there which feature the possibility to create CStr "literals" / [almost] at compile time, such as zstr! for an actual &'static CStr, or c! for a char_p::Ref<'static>, which is the "same" except for it being a slim pointer already:
Note that this can be done in addition to the impl TryInto<Symbol> API, so that people that don't know about c! or who have runtime-generated keys can still do their stuff, but be susceptible to invalid-key-related runtime failures, whereas the other cases can guarantee not hitting that runtime failure altogether