I am new to the composition approach with Rust, and I am having a hard time trying to figure out whether I could make my code more efficient / smaller.
Let us assume that I have a base struct BaseStruct:
struct BaseStruct {
   values: Vec<i32>,
}
impl BaseStruct {
    fn new() -> Self {
        Self{values: vec![]}
    }
}
Then, I define a AsBase trait to ease the composition process:
/ Trait used to do composition
trait AsBase {
   fn as_base(&mut self) -> &mut BaseStruct;
   // Note that add_val has a default implementation!
   fn add_val(&mut self, val: i32) {
       // let us assume that this method has hundreds of lines of code
       self.as_base().values.push(val);
   }
}
// Note that BaseStruct implements the AsBase trait!
impl AsBase for BaseStruct {
    fn as_base(&mut self) -> &mut BaseStruct {
        self
    }
}
Note that BaseStruct implements the AsBase trait! Otherwise, we couldn't add a value to the vector.
Then, I derive the behavior of the base struct using composition:
// Derived struct and handy functions
struct DerivedStruct {
   base: BaseStruct,
}
impl DerivedStruct {
    fn new() -> Self {
        Self{base: BaseStruct::new()}
    }
}
// Derived struct also implements the AsBase trait
impl AsBase for DerivedStruct {
    fn as_base(&mut self) -> &mut BaseStruct {
        &mut self.base
    }
}
So now, I can add values to the inner vector of my derived struct using the trait method!
fn main() {
    let mut base = BaseStruct::new();
    base.add_val(1);
    
    let mut derived = DerivedStruct::new();
    derived.add_val(1); // With composition and AsBase trait, I achieve "inheritance"
}
Here you have a playground with this example.
However, what if the add_val default method was very complex and required hundreds of lines of code? Would Rust generate a different method add_val for every struct implementing the AsBase trait? Or is the compiler smart enough to detect that they can share the same function?
Let me try to be clearer: would this alternative implementation be smaller is size, as it explicitly uses the same method?
// Base struct and handy associated methods
struct BaseStruct {
   values: Vec<i32>,
}
impl BaseStruct {
    fn new() -> Self {
        Self{values: vec![]}
    }
    fn add_val(&mut self, val: i32) {
    // Let us assume that this method is hundreds of lines long
        self.values.push(val);
    }
}
// Trait used to do composition
trait AsBase {
   fn as_base(&mut self) -> &mut BaseStruct;
   // Note that add_val has a default implementation!
   fn add_val(&mut self, val: i32) {
       self.as_base().add_val(val);
   }
}
// Note that BaseStruct does NOT implement the AsBase trait to avoid naming collision!
// Derived struct and handy functions
struct DerivedStruct {
   base: BaseStruct,
}
impl DerivedStruct {
    fn new() -> Self {
        Self{base: BaseStruct::new()}
    }
}
// Derived struct also implements the AsBase trait
impl AsBase for DerivedStruct {
    fn as_base(&mut self) -> &mut BaseStruct {
        &mut self.base
    }
}
fn main() {
    let mut base = BaseStruct::new();
    base.add_val(1);
    
    let mut derived = DerivedStruct::new();
    derived.add_val(1); // With composition and AsBase trait, I achieve "inheritance"
}
(Also, note that I couldn't implement the AsBase trait for BaseStruct due to naming collisions, I don't know if there is a workaround to avoid this other than changing the names of the methods).
Here you have a playground for the alternative version.
 
    