First up: I am a very newbie with Rust; learning.
This issue arises most probably from thinking in terms of other languages. So most probably the best solution is doing this in a completely different way. Things don't even compile yet, so apologies if the code has fundamental problems.
I am defining my first trait. The trait function takes 2 parameters, which will define the output.
trait SkFormatter {
fn to_sk(&self, key:Key, is_foreign: bool) -> String;
}
The idea is that the implementation would take a string variable, then prepend a string depending on the key, and append a string if is_foreign
(this latter part is not relevant to the question).
E.g.
MT-1c2af34
WD-54bdf36-FX
WD-ad3425b
As those strings are constant, I was thinking I could do this as a global mapping. So I first created
pub enum Key {
// there are 7 items, but keeping it short here
Metal,
Wood,
}
Then I wanted to create the mapping, and things started to get tricky. Tried the HashMap first:
use std::collections::HashMap;
static KEY_TO_PRE:HashMap<Key,&str> = HashMap::from([
(Key::Metal,"MT-"),
(Key::Wood, "WD-"),
]);
But this was complaining with
the trait bound
Key: std::hash::Hash
is not satisfied
Which is surprising to me, as it seems to suggest that the key is not hashable, but I am not defining a type for it, and I would assume that a "unit-like" enum type, as documented, is some kind of integer or something?
I have seen the match
idiom, maybe I should try that just inside the implementation (global resp. static stuff is smelly to me), but it's not clear to me if the match thing optimizes for reusing, as it will be called over and over.
Just learning...
But this was complaining with
the trait bound
Key: std::hash::Hash
is not satisfiedWhich is surprising to me, as it seems to suggest that the key is not hashable, but I am not defining a type for it, and I would assume that a "unit-like" enum type, as documented, is some kind of integer or something?
The answer to this is to derive the necessary traits on your key type:
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum Key {
// there are 7 items, but keeping it short here
Metal,
Wood,
}
I have seen the
match
idiom, maybe I should try that just inside the implementation (global resp. static stuff is smelly to me), but it's not clear to me if the match thing optimizes for reusing, as it will be called over and over.
I'm not sure what you mean by "optimizes for reusing". But generally we would use match
if all the strings are known at compile time:
impl Key {
fn to_prefix(self) -> &'static str {
match self {
Self::Metal => "MT-",
Self::Wood => "WD-",
// etc
}
}
}
Then use that in your to_sk
function.