'How to share same implementation and maybe share fields

How can I simplify this code? I still can't wrap my head around rust's traits and structs after OOP.

struct Player {
    entity: Entity,
    hp: i32,
    atk: i32
}

struct Chest {
    entity: Entity,
    amount: i32
}

impl Drawable for Chest {
    fn draw(&self, mut pencil: Pencil) {
        pencil.draw(&self.entity);
    }
}

impl Drawable for Player {
    fn draw(&self, mut pencil: Pencil) {
        pencil.draw(&self.entity);
    }
}

Maybe there is a way to inherit some fields like in OOP?

Also, if anybody knows a good and clear tutorial about traits and structs in rust, I would be very glad if you shared it!



Solution 1:[1]

In my experience, typically when you want to "share attributes" like this you typically want to break the structs into their own types and implement the traits you need on each.

Consider if your structs looked like this:

struct DrawableEntity {
    entity: Entity,
    ... // other stuff you might need to draw
}

struct Chest {
    drawable: DrawableEntity,
    ...
}

struct Player {
    drawable: DrawableEntity,
    ...
}

impl Drawable for DrawableEntity { ... }

Then in your code it might look like this:

player.drawable.draw(mut pencil);
chest.drawable.draw(mut pencil);

Solution 2:[2]

Since your impl blocks do the exact same thing with a different type, you can abstract that out into a macro so that is is trivial to repeat for any new Drawable types:

macro_rules! impl_drawable {
    ($t:ty) => {
        impl Drawable for $t {
            fn draw(&self, mut pencil: Pencil) {
                pencil.draw(&self.entity);
            }
        }
    };
}

impl_drawable!(Chest);
impl_drawable!(Player);

However, that is about all I think you can do, traits can't have fields like an abstract class in an OOP language would, so you can't really "share" the idea of having an Entity in a struct.

If you haven't read this already, the book has a chapter that talks a bit about common OOP patterns and how they translate to idiomatic Rust.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 wannabe
Solution 2 Jeremy Meadows