I'm having difficulty with the following code:
trait HelloPhrase {
fn hello(&self, to: &'static str);
}
pub enum GetHelloResult<H: HelloPhrase> {
Matched(H),
NoMatch,
}
struct English;
impl English {
pub fn new() -> English {
English
}
}
impl HelloPhrase for English {
fn hello(&self, to: &'static str) {
println!("Hello {}.", to)
}
}
struct Phrases<H: HelloPhrase> {
hello_phrases: std::collections::HashMap<&'static str, H>,
}
impl<H: HelloPhrase> Phrases<H> {
pub fn new() -> Phrases<H> {
Phrases { hello_phrases: std::collections::HashMap::new() }
}
pub fn add_hello_phrase(&mut self, lang: &'static str, hello_phrase: H) {
self.hello_phrases.insert(lang, hello_phrase);
}
pub fn get_hello(&self, lang: &'static str) -> GetHelloResult<H> {
match self.hello_phrases.get(lang) {
Some(hello_phrase) => return GetHelloResult::Matched(hello_phrase),
_ => return GetHelloResult::NoMatch,
};
}
}
fn main() {
let mut hs = Phrases::new();
hs.add_hello_phrase("english", English::new());
match hs.get_hello("english") {
GetHelloResult::Matched(hello_phrase) => hello_phrase.hello("Tom"),
_ => println!("HelloPhrase not found"),
}
}
HelloPhrase
is a trait for a language to implement, English, Russian, etc. Phrases
is a manager struct, which could have many maps of language-to-phrase. This is a contrived example, but you could think of this as an event manager (that is, get the event handlers for X input), or as an HTTP handler and router.
With that said, I'm having difficulty understanding how to borrow ownership of a HelloPhrase
to return it to the caller. Running it, returns the following error:
<anon>:40:66: 40:78 error: mismatched types:
expected `H`,
found `&H`
(expected type parameter,
found &-ptr) [E0308]
<anon>:40 Some(hello_phrase) => return GetHelloResult::Matched(hello_phrase),
^~~~~~~~~~~~
I've tried adding:
pub fn get_hello(&self, lang: &'static str) -> GetHelloResult<&H> {
and
pub enum GetHelloResult<H: HelloPhrase> {
Matched(&H),
NoMatch,
}
which results in the following error:
<anon>:7:13: 7:15 error: missing lifetime specifier [E0106]
<anon>:7 Matched(&H),
I'm having trouble adding a lifetime to the enum - in theory I want the lifetime of the returned value to be that of the Phrases
struct - but the lifetime syntax is quite confusing to me so far. To sum this up into two questions:
- How do I add a lifetime to
GetHelloResult
, to satisfy this error? - Based on ownership rules with Rust, is what I'm trying to do an anti-pattern with Rust? What might be a better design for something like this?
Based on the documentation, I know how to use a lifetime on a struct, but I do not know how to add a lifetime to an enum (syntax wise). I only mentioned struct lifetime because I assume that's a missing part, but I honestly don't know. Furthermore, if I add a lifetime to the struct and impl and attempt to add it to the hello_phrases
map, I get the error
the parameter type `H` may not live long enough [E0309]