I have a structure like this:
use std::sync::{Arc, Mutex, MutexGuard};
trait MyTrait {
fn do_something(&self);
}
#[derive(Clone)]
struct Wrapper {
object: Arc<Mutex<dyn MyTrait>>,
}
struct MyStruct1;
impl MyStruct1 {
fn specific_method(&self) {
println!("specific method");
}
}
impl MyTrait for MyStruct1 {
fn do_something(&self) {
println!("struct 1 is doing something");
}
}
fn add_object_1(vector: &mut Vec<Wrapper>) {
let object_1: MyStruct1 = MyStruct1 {};
vector.push(Wrapper {
object: Arc::new(Mutex::new(object_1)),
});
}
fn do_something_with_struct_1(object: MyStruct1) {
object.specific_method();
}
fn main() {
let mut my_objects: Vec<Wrapper> = Vec::new();
// add from a different scope
add_object_1(&mut my_objects);
// get back object_1 from my_objects
let wrapper: Wrapper = my_objects[0].clone();
let object_1_guard: MutexGuard<'_, dyn MyTrait> = wrapper.object.lock().unwrap();
// somehow get back to a MyStruct1
let object_1: MyStruct1 = todo!(); // ???
do_something_with_struct_1(object_1);
}
Essentially, there's some data structure storing a bunch of wrappers that themselves store a dynamic reference to a MyTrait object. I am currently wrapping it in Arc<Mutex<>> because that is the only way I found to enable cloning my Wrapper (which I need)
My question is now, how do I get back the specific object I added from a different function / scope from my vector?
I tried solutions from a different question that involved casting it as Arc<dyn Any + Send + Sync> (and added the Send + Sync requirements to MyTrait) but that did not work, because "the size for values of type (dyn MyTrait + 'static) cannot be known at compilation time" and the cast requires it.
I can't change it to an Enum either, because I want to be able to add new MyTrait objects from outside the crate which, to my knowledge is impossible with Enums