#how to do type erasure in traits with Associated Types

11 messages · Page 1 of 1 (latest)

sterile canopy
#

I need some guidance on a trait design pattern—basic setup is as follows:


/// driver performs operations on a Target
trait Driver {
     type Manager: DriverManager; // used to associate a driver manager
     type DriverError: Error;
     fn driver_op_1(&self, ...);
     fn driver_op_2(&self. ...);
}

/// initializes a Targets based on TargetTraits
trait DriverManager {
     type Object;
     type ManagerError: Error;
     fn manage_op_1(&self, ...); //
}

trait TargetTraits {
    fn target_op_1(&self,...);
}

struct DriverA {}
impl Driver for DriverA { ... }

impl DriverManager for DriverA { ... }

I would like to erase DriverManager from DriverA so I can Vec<Box<dyn Driver>> I feel that my setup is an anti-pattern, but I am not sure how to pattern it correctly. I do have complete control over this so I can change my approach, so any feedback is very much appreciated.

remote folio
#

When making the trait object you must specify the type of the associated type. You can't erase it

sterile canopy
#

and may be i need to refactor this in some other way.

#

that kinda sucks 🙂

#

what could be a better design pattern then ?

remote folio
#

And how you want to use the result

sterile canopy
#

Happy to explain,

So given a bit more context, I am building a subset of an operating system's virtual filesystem which will multiplex and direct the operations to the correct underlying driver based on the path being accessed (essentially mountpoints become the triggers of which driver to use) ... What I would like to do is build a registry for these drivers and then select between them—the drivers are runtime configurable, and same driver may be used in different configurations at different paths (so multiple instances) there is a collection of mount points that maintains the relevant configured driver instance, — for sake of discussion let's assume it's a HashMap ... so HashMap<OsString, Box<dyn Driver>>, of course the type Manager causes the issue 😢

The only other way that I was thinking was that either I just drop the idea of the Manager as an AT and create a combined trait:



trait StoreDriver {
  fn read(&self, ...);
  fn open(&self, ...); // etc.
}

trait UnattachedManager 
{
  fn attach(&self, s: Store, mount_point: Path); // mount stores to path
  fn detach(&self, );
}

trait ManagedStore: StoreDriver + UnattachedManager<D> {};

#

and do something like dyn Error for all error handling

#

Oooh