traits.rs
· 3.2 KiB · Rust
Raw
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 | } |