During implementation of a low-level USB driver in Rust, I've bumped into a design problem. I have the following components that need to play together:
MyDriver high-level API
A high-level public API which serves as the main entry point for driver calls:
pub struct MyDriver {
device_handle: MyDeviceHandle,
device_type: Box<dyn DeviceType>
}
Device Handle
The device handle wraps around the rusb DeviceHandle and implement some driver-specific logic around libusb calls.
extern crate rusb;
use rusb::{DeviceHandle, GlobalContext};
pub struct MyDeviceHandle {
usb_handle: DeviceHandle<GlobalContext>
}
Common Library Functions
Most common functions are handled easily just by passing them to the USB handle:
impl MyDriver {
pub fn foo(self) {
self.usb_handle.handle_foo();
}
}
Device-specific Functions
This is where things get tricky. Some library functions depend on the active device found at runtime. So I created a common trait for that, and the crux is that each DeviceType
also requires access to MyDeviceHandle
in order to implement its logic.
impl DeviceType for DeviceA {
pub fn goo(self, usb_handle: &MyDeviceHandle) {
usb_handle.one_thing();
}
}
impl DeviceType for DeviceB {
pub fn goo(self, usb_handle: &MyDeviceHandle)
usb_handle.other_thing();
}
}
Currently the only way to have MyDeviceHandle
available to each DeviceType
is to pass a reference to it in each implemented function.
Is there a nice way to have a struct that has some shared ownership of MyDeviceHandle
that can be instantiated upon construction and then re-used from each function?
Aucun commentaire:
Enregistrer un commentaire