Possible to dynamic dispatch on `Device` trait?
Opened this issue · 2 comments
I am trying to put different Device
implementations into something like Box<dyn Device>
. Moreover, I want to have something looks like
struct NetInterface {
device: Box<dyn Device>,
iface: Interface,
sockets: SocketSet<'static>,
}
Without which, I have to write a lot of duplicate codes to support multiple physical network interfaces. However the trait doesn't meet object safe requirements. I wonder if this can be done with some tricks.
Is doing something like the following forcing you to write a lot of duplicate code?
struct NetInterface<D> {
device: D,
iface: Interface,
sockets: SocketSet<'static>,
}
I have a similar problem — I'm working on a virtual ethernet switch that operates over a variable number of unknown phy::Device
s:
struct VSwitch<'a, const MAX_DEVICES: usize> {
devices: heapless::Vec<MAX_DEVICES, &'a mut dyn smoltcp::phy::Device>,
}
This isn't possible with the current phy::Device
trait as it's not object-safe.
I'm considering a wrapper/"trampoline" trait that impls phy::Device
with TxToken
and RxToken
specialized to my crate, something like:
// These need to wrap the {Rx,Tx}Token traits, which I *think* (hope) can be done
// with a closure -- might be impossible.
struct MyCrateTxToken;
struct MyCrateRxToken;
trait DeviceTrampoline {
fn receive(&mut self, timestamp: Instant) -> Option<(MyCrateRxToken, MyCrateTxToken)>;
fn transmit(&mut self, timestamp: Instant) -> Option<MyCrateTxToken>;
fn capabilities(&self) -> DeviceCapabilities;
}
impl<T> DeviceTrampoline for T
where T: phy::Device {
/* delegate */
}
// Now (I think) I can have:
struct VSwitch<'a, const MAX_DEVICES: usize> {
devices: heapless::Vec<MAX_DEVICES, &'a mut dyn DeviceTrampoline>,
}
This feels unfortunate in that I think dynamic dispatch for phy::Device
is generally useful, yet there isn't a canonical object-safe wrapper. That said, I'm not sure there's anything that can be done in smoltcp
while maintaining the flexibility of TxToken
and RxToken
— I just wanted to provide another data point.