I want to create driver mappings for some Unix devices. To efficiently access the driver files, I want to keep the file handle opened after the first access, so I want to store an access wrapper in a map. Each device has different (but sometimes common) methods.
In an OOP-based language like Java, I would create an abstract class with this map and derivatives that access this map.
class Attribute {
void doSomething() { /* Do Something */ }
}
abstract class Device {
Map<String, Attribute> attributes = new HashMap<>();
}
class Motor extends Device {
void func1() {
attributes.get("elem1").do_something();
}
}
class SpecialMotor extends Motor {
void func2() {
attributes.get("elem2").do_something();
}
}
class Sensor extends Device {
void func1() {
attributes.get("elem1").do_something();
// Its possible that this function has a different return type
}
}
As far as I know, this is not possible in Rust. I tried to emulate this behavior with a trait to access this map, but this creates a lot of boilerplate code for each device.
struct Attribute {}
impl Attribute {
fn do_something() {}
}
trait Device {
fn get_attributes(&self) -> HashMap<String, Attribute>;
}
trait Motor: Device {
fn func1(&self) {
self.get_attributes()["elem1"].do_something();
}
}
trait SpecialMotor: Motor {
fn func2(&self) {
self.get_attributes()["elem2"].do_something();
}
}
trait Sensor: Device {
fn func1(&self) {
self.get_attributes()["elem1"].do_something();
}
}
struct MotorImpl {
attributes: HashMap<String, Attribute>,
}
impl MotorImpl {
fn new() -> MotorImpl {
MotorImpl {
attributes: HashMap::new(),
}
}
}
impl Motor for MotorImpl {
fn get_attributes(&self) -> HashMap<String, Attribute> {
self.attributes
}
}
struct SpecialMotorImpl {
attributes: HashMap<String, Attribute>,
}
impl SpecialMotorImpl {
fn new() -> SpecialMotorImpl {
SpecialMotorImpl {
attributes: HashMap::new(),
}
}
}
impl SpecialMotor for SpeicalMotorImpl {
fn get_attributes(&self) -> HashMap<String, Attribute> {
self.attributes
}
}
struct SensorImpl {
attributes: HashMap<String, Attribute>,
}
impl SensorImpl {
fn new() -> SensorImpl {
SensorImpl {
attributes: HashMap::new(),
}
}
}
impl Sensor for SensorImpl {
fn get_attributes(&self) -> HashMap<String, Attribute> {
self.attributes
}
}
Is it possible have a kind of common attribute for multiple traits or is there an even better design pattern to achieve this?