traits.rs
· 3.2 KiB · Rust
Ham
Playground
#[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<HealthComp> for Player {
fn as_ref(&self) -> &HealthComp {
&self.health_comp
}
}
impl AsMut<HealthComp> for Player {
fn as_mut(&mut self) -> &mut HealthComp {
&mut self.health_comp
}
}
impl AsRef<WeaponComp> for Player {
fn as_ref(&self) -> &WeaponComp {
&self.weapon_comp
}
}
impl AsMut<WeaponComp> 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<HealthComp> for Enemy {
fn as_ref(&self) -> &HealthComp {
&self.health_comp
}
}
impl AsMut<HealthComp> for Enemy {
fn as_mut(&mut self) -> &mut HealthComp {
&mut self.health_comp
}
}
impl AsRef<WeaponComp> for Enemy {
fn as_ref(&self) -> &WeaponComp {
&self.weapon_comp
}
}
impl AsMut<WeaponComp> for Enemy {
fn as_mut(&mut self) -> &mut WeaponComp {
&mut self.weapon_comp
}
}
trait AttackTrait<T>
where
T: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp>,
Self: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp>,
{
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::<WeaponComp>::as_ref(&other).power;
let defence_power = AsRef::<WeaponComp>::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<T> AttackTrait<T> for Enemy where
T: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp>
{
}
impl<T> AttackTrait<T> for Player where
T: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp>
{
}
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,
},
};
<Player as AsMut<HealthComp>>::as_mut(&mut player).hurt(5);
<Enemy as AsMut<HealthComp>>::as_mut(&mut enemy).hurt(8);
enemy.parry(&mut player);
println!("{:?}\n {:?}", player, enemy);
}
| 1 | #[derive(Debug)] |
| 2 | enum WeaponType { |
| 3 | Sword, |
| 4 | Club, |
| 5 | } |
| 6 | |
| 7 | #[derive(Debug)] |
| 8 | struct WeaponComp { |
| 9 | weapon: WeaponType, |
| 10 | power: i32, |
| 11 | } |
| 12 | |
| 13 | #[derive(Debug)] |
| 14 | struct HealthComp { |
| 15 | health: i32, |
| 16 | } |
| 17 | |
| 18 | trait HealthTrait { |
| 19 | fn hurt(&mut self, amount: i32); |
| 20 | fn heal(&mut self, amount: i32); |
| 21 | } |
| 22 | |
| 23 | impl HealthTrait for HealthComp { |
| 24 | fn hurt(&mut self, amount: i32) { |
| 25 | self.health -= amount; |
| 26 | } |
| 27 | |
| 28 | fn heal(&mut self, amount: i32) { |
| 29 | self.health += amount; |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | #[derive(Debug)] |
| 34 | struct Player { |
| 35 | health_comp: HealthComp, |
| 36 | weapon_comp: WeaponComp, |
| 37 | } |
| 38 | |
| 39 | impl AsRef<HealthComp> for Player { |
| 40 | fn as_ref(&self) -> &HealthComp { |
| 41 | &self.health_comp |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | impl AsMut<HealthComp> for Player { |
| 46 | fn as_mut(&mut self) -> &mut HealthComp { |
| 47 | &mut self.health_comp |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | impl AsRef<WeaponComp> for Player { |
| 52 | fn as_ref(&self) -> &WeaponComp { |
| 53 | &self.weapon_comp |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | impl AsMut<WeaponComp> for Player { |
| 58 | fn as_mut(&mut self) -> &mut WeaponComp { |
| 59 | &mut self.weapon_comp |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | #[derive(Debug)] |
| 64 | struct Enemy { |
| 65 | health_comp: HealthComp, |
| 66 | weapon_comp: WeaponComp, |
| 67 | } |
| 68 | |
| 69 | impl AsRef<HealthComp> for Enemy { |
| 70 | fn as_ref(&self) -> &HealthComp { |
| 71 | &self.health_comp |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | impl AsMut<HealthComp> for Enemy { |
| 76 | fn as_mut(&mut self) -> &mut HealthComp { |
| 77 | &mut self.health_comp |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | impl AsRef<WeaponComp> for Enemy { |
| 82 | fn as_ref(&self) -> &WeaponComp { |
| 83 | &self.weapon_comp |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | impl AsMut<WeaponComp> for Enemy { |
| 88 | fn as_mut(&mut self) -> &mut WeaponComp { |
| 89 | &mut self.weapon_comp |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | trait AttackTrait<T> |
| 94 | where |
| 95 | T: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp>, |
| 96 | Self: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp>, |
| 97 | { |
| 98 | fn attack(&self, other: &mut T) { |
| 99 | let weapon: &WeaponComp = self.as_ref(); |
| 100 | let target: &mut HealthComp = other.as_mut(); |
| 101 | |
| 102 | target.hurt(weapon.power); |
| 103 | } |
| 104 | |
| 105 | fn parry(&mut self, other: &mut T) { |
| 106 | let attack_power = AsRef::<WeaponComp>::as_ref(&other).power; |
| 107 | let defence_power = AsRef::<WeaponComp>::as_ref(&self).power; |
| 108 | |
| 109 | let mut target: &mut HealthComp = if defence_power > attack_power { |
| 110 | other.as_mut() |
| 111 | } else { |
| 112 | self.as_mut() |
| 113 | }; |
| 114 | |
| 115 | target.hurt((attack_power - defence_power).abs()); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | impl<T> AttackTrait<T> for Enemy where |
| 120 | T: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp> |
| 121 | { |
| 122 | } |
| 123 | |
| 124 | impl<T> AttackTrait<T> for Player where |
| 125 | T: AsRef<WeaponComp> + AsRef<HealthComp> + AsMut<WeaponComp> + AsMut<HealthComp> |
| 126 | { |
| 127 | } |
| 128 | |
| 129 | fn main() { |
| 130 | let mut player = Player { |
| 131 | health_comp: HealthComp { health: 10 }, |
| 132 | weapon_comp: WeaponComp { |
| 133 | weapon: WeaponType::Sword, |
| 134 | power: 5, |
| 135 | }, |
| 136 | }; |
| 137 | |
| 138 | let mut enemy = Enemy { |
| 139 | health_comp: HealthComp { health: 10 }, |
| 140 | weapon_comp: WeaponComp { |
| 141 | weapon: WeaponType::Sword, |
| 142 | power: 2, |
| 143 | }, |
| 144 | }; |
| 145 | |
| 146 | <Player as AsMut<HealthComp>>::as_mut(&mut player).hurt(5); |
| 147 | <Enemy as AsMut<HealthComp>>::as_mut(&mut enemy).hurt(8); |
| 148 | |
| 149 | enemy.parry(&mut player); |
| 150 | |
| 151 | println!("{:?}\n {:?}", player, enemy); |
| 152 | } |