#[derive(Debug)] enum WeaponType { Sword, Club, } #[derive(Debug)] struct WeaponComp { weapon: WeaponType, power: i32, } #[derive(Debug)] struct HealthComp { health: i32, } trait HealthTrait { fn hurt(&mut self, amount: i32); fn heal(&mut self, amount: i32); } impl HealthTrait for HealthComp { fn hurt(&mut self, amount: i32) { self.health -= amount; } fn heal(&mut self, amount: i32) { self.health += amount; } } #[derive(Debug)] struct Player { health_comp: HealthComp, weapon_comp: WeaponComp, } impl AsRef for Player { fn as_ref(&self) -> &HealthComp { &self.health_comp } } impl AsMut for Player { fn as_mut(&mut self) -> &mut HealthComp { &mut self.health_comp } } impl AsRef for Player { fn as_ref(&self) -> &WeaponComp { &self.weapon_comp } } impl AsMut for Player { fn as_mut(&mut self) -> &mut WeaponComp { &mut self.weapon_comp } } #[derive(Debug)] struct Enemy { health_comp: HealthComp, weapon_comp: WeaponComp, } impl AsRef for Enemy { fn as_ref(&self) -> &HealthComp { &self.health_comp } } impl AsMut for Enemy { fn as_mut(&mut self) -> &mut HealthComp { &mut self.health_comp } } impl AsRef for Enemy { fn as_ref(&self) -> &WeaponComp { &self.weapon_comp } } impl AsMut for Enemy { fn as_mut(&mut self) -> &mut WeaponComp { &mut self.weapon_comp } } trait AttackTrait where T: AsRef + AsRef + AsMut + AsMut, Self: AsRef + AsRef + AsMut + AsMut, { fn attack(&self, other: &mut T) { let weapon: &WeaponComp = self.as_ref(); let target: &mut HealthComp = other.as_mut(); target.hurt(weapon.power); } fn parry(&mut self, other: &mut T) { let attack_power = AsRef::::as_ref(&other).power; let defence_power = AsRef::::as_ref(&self).power; let mut target: &mut HealthComp = if defence_power > attack_power { other.as_mut() } else { self.as_mut() }; target.hurt((attack_power - defence_power).abs()); } } impl AttackTrait for Enemy where T: AsRef + AsRef + AsMut + AsMut { } impl AttackTrait for Player where T: AsRef + AsRef + AsMut + AsMut { } fn main() { let mut player = Player { health_comp: HealthComp { health: 10 }, weapon_comp: WeaponComp { weapon: WeaponType::Sword, power: 5, }, }; let mut enemy = Enemy { health_comp: HealthComp { health: 10 }, weapon_comp: WeaponComp { weapon: WeaponType::Sword, power: 2, }, }; >::as_mut(&mut player).hurt(5); >::as_mut(&mut enemy).hurt(8); enemy.parry(&mut player); println!("{:?}\n {:?}", player, enemy); }