Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make a struct that works with both values and borrowed references to a trait?

I want to make a struct that wraps another type but can take both owned and borrowed version of values that implement a given trait.

For example, let's say I have the trait Foobar:

trait Foobar {
    fn foobar(&self);
}

I now want to make a struct that wraps values or borrowed references of this trait:

struct FoobarWrapper<T: Foobar> {
    wrapped: T,
    extra_stuff: Stuff
}

Here, I want FoobarWrapper to work with both Baz and &Baz given that impl Foobar for Baz.

I have come up with one solution that might work but I don't know if it's idiomatic and that's to simply do:

impl<'a, T: Foobar> Foobar for &'a T  {
    fn foobar(&self) {
        (*self).foobar()
    }
}

If I'm not mistaken, this makes any reference to a value that implements Foobar also an implementor of Foobar. But is this the way you're supposed to do it?

like image 804
Emil Eriksson Avatar asked Sep 15 '15 02:09

Emil Eriksson


1 Answers

Yes, your solution is probably fine if you can support it. Iterator does the same thing with

impl<'a, I> Iterator for &'a mut I where I: Iterator + ?Sized

You should probably also add the ?Sized bound too, for flexibility.

like image 112
Veedrac Avatar answered Sep 30 '22 04:09

Veedrac