I'm having trouble with implementing a trait bound generic parameter for an entity that sends messages to a proper entity depending on the message. Imagine a trait called MessageTrait and MessageSender:
pub trait MessageTrait: Serialize + Clone + PartialEq {} // trait to allow concrete message (e.g. Message2) to be substituted in MessageSender
pub trait MessageSender {
fn send_message(&mut self, message: &Message);
}
And messages message1..messageN (only Messag1 shown):
// messages to send
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct Message1 {}
impl MessageTrait for Message1 {}
And protocol specific MessageSender that sends MessageX using UDP:
// UDP send
pub struct UdpSender { // UpdSender fields }
impl MessageSender for UdpSender {
fn send_message(&mut self, message: &Message1) {
let send_msg = message.clone();
// ... do stuff to send data using UDP
}
}
// impl MessageSender for UdpSender { ... }
And finally, a HashMap containing the MessageSenders keyed by a String that can be used find the correct MessageSender:
// Message Router
struct MessageRouter {
HashMap maps;
}
impl MessageRouter {
pub fn send_msg(&mut self, id: &str) {
// ...
if let Some(sender) = maps.get(id) { // find sender in map
sender.send_message(message)
}
}
The code above compiles, but, I would like to change the MessageRouter to take a generic type so I can substitute something other than UdpSender (e.g. TCP/Unix Socket or Stub for testing):
struct MessageRouter {
HashMap>, maps; // error
}
but the following gives me an error: expected a type, found a trait
impl MessageRouter where T: MessageSender { // error
pub fn new() -> Self {
Self {
maps: HashMap::new(),
}
}
pub fn send_msg(&mut self, id: &str, msg: &T) {
// ...
if let Some(sender) = maps.get_mut(id) {
sender.send_message(msg);
..
}
}
}
Also tried MessageSender, but this doesn't work either. How can I define T to be a type that implements MessageSender trait so it can be used as a type HashMap