You can either add a type parameter to your struct, as in Zernike's answer, or use a trait object.

Using the type parameter is better for performance because each value of T will create a specialized copy of the struct, which allows for static dispatch. A trait object uses dynamic dispatch so it lets you swap the concrete type at runtime.

The trait object approach looks like this:

pub struct MyStruct<'a> {
    my_trait: &'a dyn MyTrait,
}

Or this:

pub struct MyStruct {
    my_trait: Box<dyn MyTrait>,
}

However, in your case, MyStruct cannot be made into an object because receive is a static method. You'd need to change it to take &self or &mut self as its first argument for this to work. There are also other restrictions.


pub struct MyStruct<T>
where
    T: MyTrait,
{
    my_trait: T,
}

or

pub struct MyStruct<T: MyTrait> {
    my_trait: T,
}

https://doc.rust-lang.org/book/second-edition/ch10-02-traits.html#trait-bounds