With the code:
trait Msg {
fn apply_to_state(&self, state: &mut State);
}
trait ApplicableToStateOne: Msg {
fn apply_to_state(&self, state: &mut State) {
match state {
State::StateOne(s) => {
self.apply_to_state_one(s)
}
_ => {
//TODO: return an error
}
}
}
fn apply_to_state_one(&self, state_one: &mut StateOne);
}
#[derive(Debug, Clone)]
pub struct MsgA {
pub field_a: u8,
}
impl Msg for MsgA {}
impl ApplicableToStateOne for MsgA {
fn apply_to_state_one(&self, state_one: &mut StateOne) {
state_one.one_special += 31; // just a mutability test
}
}
// this is a stub for receiving different kinds of messages from the network
fn recv() -> Box<dyn Msg> {
Box::new(MsgA { field_a: 42 })
}
fn main() {
let mut state = State::StateOne(StateOne { common: 0, one_special: 1 });
for _ in 0..100 { // this would be loop, but that makes the playground timeout
let incoming = recv(); // this would block
incoming.apply_to_state(&mut state)
}
}
( playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7c89a2bbc765380fc002864e2be80e55 )
the compiler complains:
error[E0046]: not all trait items implemented, missing: `apply_to_state`
--> src/bin/sandbox6.rs:83:1
|
2 | fn apply_to_state(&self, state: &mut State);
| -------------------------------------------- `apply_to_state` from trait
...
83 | impl Msg for MsgA {}
| ^^^^^^^^^^^^^^^^^ missing `apply_to_state` in implementation
In my (obviously deficient) understanding, I would have expected the trait ApplicableToStateOne implementation of apply_to_state to be called.
How can I make this happen?
Update:
More abstractly, this question is about:
- receiving a boxed supertrait object from the network, then
- finding out which subtrait it has, and finally
- calling a method appropriate for the subtrait (perhaps through the supertrait in some way).
This can all be done, rather verbosely, using enums instead of traits, but that adds a hierarchy of enums.
Having a hierarchy of enums is bad because:
- it adds unnecessary bytes to the serialisation, and because
- there can be only one such hierarchy, which prevents classification of messages in any other way.