Hello,
Let say I have the following trait :
pub trait Driver: Debug + Send {
fn make_packet(command: &Command) -> Result<Packet, DriverError>
where
Self: Sized;
fn try_parse(data: &[u8]) -> ParseResult
where
Self: Sized;
}
The idea is that I want to be able to have different "Driver" but they have no need for a internal state so both function do not use self
.
Now I have another trait called Port
that abstract reading some byte and using the Driver to parse those byte. I would write it like so:
pub trait PortIn: Read + Debug {
fn try_read_notification<D: Driver>(&mut self) -> PortTryRead {
// the actual implementation is irrelevant.
}
}
This has the advantage that I can just indicate to the function which driver to pass as a type indication like so : port.try_read_notification::<driver::Type1>()
.
This is fine, my issue comes because I have another trait called Task
with the following:
pub trait Task: Debug + Send {
fn execute(&mut self);
fn name(&self) -> &str;
}
Notice how execute
does not have any type parameter. But I want to be able to choose which driver and port to use withing this function.
This mean I end up having to do something very awkward where I store an object that implement Driver
in my struct just to keep the trait information:
#[derive(Debug)]
pub struct ReaderTask<D: Driver + Send, P: PortIn + Send> {
pub chan: flume::Sender<Notification>,
pub port: P,
pub _driver: D,
}
impl<D: Driver + Send, P: PortIn + Send> Task for ReaderTask<D, P> {
fn execute(&mut self) {
let res = self.port.try_read_notification::<D>();
// The rest of the code is irrelevant
}
}
Notice how _driver
is never actually used.
Is there a better way to do this ? The only ways I could think of were to either modify the trait for Task
to include a type parameter, but this is an issue because Task
is intended to be "generic", or to have a specific implementation of the Task for each combo of driver+port, which would mean creating a lot of variation of the task.
Is there a way for me to pass the trait information to the implementation of Task
without having to keep a object that implement Driver
in my task ?