Downcasting from an Arc<Mutex<dyn Trait>> in Rust?

164 Views Asked by At

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

0

There are 0 best solutions below