From what I understand, my type is missing some conversion methods but I don't see how to solve the issue...
error[E0277]: the trait bound `&ItemName: From<&K>` is not satisfied
--> src/lib.rs:30:28
|
30 | self.items.get(key.into())
| ^^^^ the trait `From<&K>` is not implemented for `&ItemName`
|
= note: required because of the requirements on the impl of `Into<&ItemName>` for `&K`
So the question would be what kind of types you want to support as key in the get method. If it’s “either &ItemName or &str” then you could add a Borrow<str> for ItemName implementation and make it work like this
My usecase is the following: I want to be able to write:
pub fn main() {
let store = Store { items: HashSet::new() };
store.insert("pineapple");
let pineapple = store.get("pineapple");
}
I tried with your given playground, but I got the following error:
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> src/main.rs:43:31
|
43 | let pineapple = store.get("pineapple");
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
Then, by following the HashSet standard implementation I added the following:
error[E0282]: type annotations needed
--> src/main.rs:43:27
|
43 | let pineapple = store.get("pineapple");
| ^^^ cannot infer type for type parameter `K` declared on the associated function `get`
Not sure how I can get my desired behaviour.
PS: In this code snippet, is K necessary? I think it's the first time I see a where not starting with a generic type name. How does it works?
In this code I don't understand the ItemName part, I thought only generics name could be placed on the left part of the colon. What does it mean and how does it work?
Well, it’s not true. Any type can go on the left side of the colon in a where clause, it just very commonly is a generic name. OTOH in the generic parameters list (i.e. between the <> / so not in the where clause) indeed ony a generic parameter name can go on the left side of the colon.
It means that only substitutions for Q can be used such that ItemName implements Borrow<Q> and Q implements Hash and Eq.
With the fixed Q: ?Sized version of the code, this means that e.g. str and ItemName are both okay since:
ItemName derives Eq and Hash, so that with Q == ItemName, Q: Hash + Eq isfulfilled,
and also there’s a generic implementation impl<T> Borrow<T> for Tin the standard library so that indeed with Q == ItemName, we have ItemName: Borrow<Q> i.e. ItemName: Borrow<ItemName> as a special case of the generic implementation, obtained by substituting T == ItemName in T: Borrow<T>.
str is an unsized type, hence the ?Sized qualifier is necessary for it to be usable. With Q == str, you have Q: Hash + Eq, i.e. str: Hash + Eq from the standard library (here and here), and there’s the impl Borrow<str> for ItemName implementation in the playground that provides ItemName: Borrow<str>.