I'm coming to Rust from a background of Java, C#, C++, as well as limited C knowledge. I switched to Rust because I thought the design patterns and the type safety would greatly improve my final product. I'm not great at writing these kinds of things, so I've made a list of my goals and the problem I am having.
Goals:
- I want a
Vec
or any list that stores different objects that implement a common trait.- The trait has two generic types that are defined by the object that implements it.
- Each object stored in the list would be unique, meaning the object would have unique objects defined for the implementation of the trait.
- Each unique object should only be in the list once.
- I would like to keep track of the generic types associated with each object. This is not my current problem nor am I worried about this detail right now, but I will not turn down advice for this.
I'm not sure what the best/safest way to store a generic type with a generic trait while still having the flexibility I would like.
// common functions in trait that use A and B.
pub trait Common<A, B> {
fn common_behavior_one(a: A) {}
fn common_behavior_two(b: B) {}
}
// these are example objects and there would be many more sets like this
struct objectA {}
struct objectB {}
struct CommonObject {} // stores list of objectA's and consumes objectB's
impl Common<objectA, objectB> for CommonObject {
fn common_behavior_one(a: objectA) {}
fn common_behavior_two(b: objectB) {}
}
//this is where my problem starts
struct Manager {
// i would like this to accept any Object with the Common trait implemented
// regardless of what the generics for the trait are.
objects: Vec<Box<impl Common>>, // problem
}
impl Manager {
pub fn add_object<A, B>(&mut self, _object: Box<Common<A, B>>) { // potential problem
// add _object to vec
}
pub fn remove_object<A, B>(&mut self, _object: Box<Common<A, B>>) { // potential problem
// remove _object from vec
}
pub fn get_object() {} // not sure about how im going to do this.
pub fn pass_to_object<B>(&mut self, _struct: Box<B>) { // potential problem
// pass _struct(B type) into common where it will be consumed.
}
}