Zhou Lebo
Zhou Lebo

Reputation: 41

Work around borrow issue generates ugly code to implement a registry of objects. Is there another way?

I want to create a registry of objects that all implement some trait. So the Registry struct has a register function. But if I declare it returning void type, I can only register one object, then borrow issue for the second one. I found a work around: the register function returns self as mutable, then I an reuse the registry returned and the compiler is OK. I found this a bit ridiculous. What is the proper way to maintain a registry of objects ? Here is the code that works

trait Doable {
    fn do_it(&mut self);
}

struct Registry<'a> {
    components: Vec<Box<&'a (dyn Doable)>>,
}

impl<'a> Registry<'a> {
    fn register(&'a mut self, d: &'a impl Doable) -> &mut Registry<'a> {
        self.components.push(Box::new(d));
        self
    }
}

struct Foo {
    name: String,
    value: u32,
}
impl Foo {
    fn set_value(&mut self, v: u32) {
        self.value = v
    }
}
impl Doable for Foo {
    fn do_it(&mut self) {
        println!("The value of {} is {}", self.name, self.value);
    }
}

struct Bar {
    nm: String,
    id: u32,
}
impl Bar {
    fn set_id(&mut self, v: u32) {
        self.id = v
    }
}
impl Doable for Bar {
    fn do_it(&mut self) {
        println!("The id of {} is {}", self.nm, self.id);
    }
}

fn main() {
    let mut r = Registry {
        components: Vec::new(),
    };
    let mut foo: Foo = Foo {
        name: "foo".to_string(),
        value: 0,
    };
    let mut bar: Bar = Bar {
        nm: "bar".to_string(),
        id: 0,
    };
    let mut baz: Foo = Foo {
        name: "baz".to_string(),
        value: 0,
    };
    let r1 = r.register(&foo);
    let r2 = r1.register(&bar);
    r2.register(&baz);
    foo.set_value(41);
    bar.set_id(5);
    baz.set_value(11);
    foo.do_it();
    bar.do_it();
    baz.do_it();
}

it works but I would like to have a better way for registering objects and then call them back using the trait...

Upvotes: 0

Views: 38

Answers (0)

Related Questions