I am trying to create a model for a network device management. Different device drivers register themselves with the manager for later use. Each driver can then create an instance of a Device
trait object, specific to that driver. Creating the Device
instance requires Driver
-impl -specific data to instantiate it.
What I have below seems like it will work, but the Any
bits are unpleasant. Is there a way to do this in the type system without requiring casting? I tried using associated types on Driver
to include what each Driver
's device_params type would be, but that didn't seem to solve my problem.
use std::any::Any;
pub struct Manager {
drivers: Vec<Box<dyn Driver>>,
devices: Vec<Box<dyn Device>>,
}
impl Manager {
pub fn register_driver(&mut self, driver: Box<dyn Driver>) { ... }
pub fn create_device_by_driver_name(&mut self, driver_name: &str, device_params: &dyn Any) { ... }
}
pub struct PlaceholderError;
pub trait Driver {
fn new_device(&mut self, device_params: &dyn Any) -> Result<Box<dyn Device>, PlaceholderError>;
fn del_device(&mut self, device: Box<dyn Device>);
fn name(&self) -> &'static str;
}
pub struct DummyDriver;
pub struct DummyDriverDeviceParams;
impl Driver for DummyDriver {
fn new_device(&mut self, params: &dyn Any) -> Result<Box<dyn Device>, ()> {
let params: &DummyDriverDeviceParams = params.downcast_ref().ok_or(PlaceholderError)?;
// use params to create an instance of DummyDriverDevice
Ok(Box::new(DummyDriverDevice{}))
}
fn del_device(&mut self, device: Box<dyn Device>) {
todo!()
}
fn name(&self) -> &'static str {
"dummy"
}
}
pub struct DummyDriverDevice {}
impl Device for DummyDriverDevice {}
pub trait Device {/* TODO */}