1use super::{Food, Iron, Resources, Stone, Wood};
5use derive_more::{Deref, Display, Into};
6use serde::{Deserialize, Serialize};
7use std::cmp::Ordering;
8use std::ops::{Add, AddAssign, Sub, SubAssign};
9
10#[derive(Clone, Debug, Default, Deserialize, Serialize)]
11#[serde(default, rename_all = "camelCase")]
12pub struct ResourcesDiff {
13 pub food: FoodDiff,
14 pub iron: IronDiff,
15 pub stone: StoneDiff,
16 pub wood: WoodDiff,
17}
18
19impl Add for ResourcesDiff {
20 type Output = Self;
21
22 fn add(self, rhs: Self) -> Self {
23 Self {
24 food: self.food + rhs.food,
25 iron: self.iron + rhs.iron,
26 stone: self.stone + rhs.stone,
27 wood: self.wood + rhs.wood,
28 }
29 }
30}
31
32impl Add<Resources> for ResourcesDiff {
33 type Output = Self;
34
35 fn add(self, rhs: Resources) -> Self {
36 Self {
37 food: self.food + rhs.food,
38 iron: self.iron + rhs.iron,
39 stone: self.stone + rhs.stone,
40 wood: self.wood + rhs.wood,
41 }
42 }
43}
44
45impl Add<ResourcesDiff> for Resources {
46 type Output = Self;
47
48 fn add(self, rhs: ResourcesDiff) -> Self {
49 Self {
50 food: self.food + rhs.food,
51 iron: self.iron + rhs.iron,
52 stone: self.stone + rhs.stone,
53 wood: self.wood + rhs.wood,
54 }
55 }
56}
57
58impl AddAssign for ResourcesDiff {
59 fn add_assign(&mut self, rhs: Self) {
60 *self = Self {
61 food: self.food + rhs.food,
62 iron: self.iron + rhs.iron,
63 stone: self.stone + rhs.stone,
64 wood: self.wood + rhs.wood,
65 };
66 }
67}
68
69impl AddAssign<Resources> for ResourcesDiff {
70 fn add_assign(&mut self, rhs: Resources) {
71 *self = Self {
72 food: self.food + rhs.food,
73 iron: self.iron + rhs.iron,
74 stone: self.stone + rhs.stone,
75 wood: self.wood + rhs.wood,
76 };
77 }
78}
79
80impl AddAssign<ResourcesDiff> for Resources {
81 fn add_assign(&mut self, rhs: ResourcesDiff) {
82 *self = Self {
83 food: self.food + rhs.food,
84 iron: self.iron + rhs.iron,
85 stone: self.stone + rhs.stone,
86 wood: self.wood + rhs.wood,
87 };
88 }
89}
90
91impl Sub for ResourcesDiff {
92 type Output = Self;
93
94 fn sub(self, rhs: Self) -> Self {
95 Self {
96 food: self.food - rhs.food,
97 iron: self.iron - rhs.iron,
98 stone: self.stone - rhs.stone,
99 wood: self.wood - rhs.wood,
100 }
101 }
102}
103
104impl Sub<ResourcesDiff> for Resources {
105 type Output = Self;
106
107 fn sub(self, rhs: ResourcesDiff) -> Self {
108 Self {
109 food: self.food - rhs.food,
110 iron: self.iron - rhs.iron,
111 stone: self.stone - rhs.stone,
112 wood: self.wood - rhs.wood,
113 }
114 }
115}
116
117impl SubAssign for ResourcesDiff {
118 fn sub_assign(&mut self, rhs: Self) {
119 *self = Self {
120 food: self.food - rhs.food,
121 iron: self.iron - rhs.iron,
122 stone: self.stone - rhs.stone,
123 wood: self.wood - rhs.wood,
124 };
125 }
126}
127
128impl SubAssign<Resources> for ResourcesDiff {
129 fn sub_assign(&mut self, rhs: Resources) {
130 *self = Self {
131 food: self.food - rhs.food,
132 iron: self.iron - rhs.iron,
133 stone: self.stone - rhs.stone,
134 wood: self.wood - rhs.wood,
135 };
136 }
137}
138
139impl SubAssign<ResourcesDiff> for Resources {
140 fn sub_assign(&mut self, rhs: ResourcesDiff) {
141 *self = Self {
142 food: self.food - rhs.food,
143 iron: self.iron - rhs.iron,
144 stone: self.stone - rhs.stone,
145 wood: self.wood - rhs.wood,
146 };
147 }
148}
149
150macro_rules! decl_resource_diff {
151 ($($resource:ident),+ $(,)?) => {
152 paste::paste! {
153 $(
154 #[derive(
155 Clone,
156 Copy,
157 Debug,
158 Default,
159 Deref,
160 Display,
161 Into,
162 PartialEq,
163 Eq,
164 PartialOrd,
165 Ord,
166 Deserialize,
167 Serialize,
168 )]
169 #[into(i32, f64)]
170 pub struct [<$resource Diff>](i32);
171
172 impl [<$resource Diff>] {
173 #[inline]
174 pub const fn new(value: i32) -> Self {
175 Self(value)
176 }
177
178 #[inline]
179 pub const fn zero() -> Self {
180 Self(0)
181 }
182 }
183
184 impl PartialEq<i32> for [<$resource Diff>] {
185 fn eq(&self, other: &i32) -> bool {
186 self.0.eq(other)
187 }
188 }
189
190 impl PartialOrd<i32> for [<$resource Diff>] {
191 fn partial_cmp(&self, other: &i32) -> Option<Ordering> {
192 self.0.partial_cmp(other)
193 }
194 }
195
196 impl Add for [<$resource Diff>] {
197 type Output = Self;
198
199 fn add(self, rhs: Self) -> Self {
200 Self(self.0.saturating_add(rhs.0))
201 }
202 }
203
204 impl Add<$resource> for [<$resource Diff>] {
205 type Output = Self;
206
207 fn add(self, rhs: $resource) -> Self {
208 Self(self.0.saturating_add_unsigned(rhs.0))
209 }
210 }
211
212 impl Add<[<$resource Diff>]> for $resource {
213 type Output = Self;
214
215 fn add(self, rhs: [<$resource Diff>]) -> Self {
216 Self(self.0.saturating_add_signed(rhs.0))
217 }
218 }
219
220 impl Add<i32> for [<$resource Diff>] {
221 type Output = Self;
222
223 fn add(self, rhs: i32) -> Self {
224 Self(self.0.saturating_add(rhs))
225 }
226 }
227
228 impl Add<u32> for [<$resource Diff>] {
229 type Output = Self;
230
231 fn add(self, rhs: u32) -> Self {
232 Self(self.0.saturating_add_unsigned(rhs))
233 }
234 }
235
236 impl AddAssign for [<$resource Diff>] {
237 fn add_assign(&mut self, rhs: Self) {
238 *self = *self + rhs;
239 }
240 }
241
242 impl AddAssign<$resource> for [<$resource Diff>] {
243 fn add_assign(&mut self, rhs: $resource) {
244 *self = *self + rhs;
245 }
246 }
247
248 impl AddAssign<[<$resource Diff>]> for $resource {
249 fn add_assign(&mut self, rhs: [<$resource Diff>]) {
250 *self = *self + rhs;
251 }
252 }
253
254 impl AddAssign<i32> for [<$resource Diff>] {
255 fn add_assign(&mut self, rhs: i32) {
256 *self = *self + rhs;
257 }
258 }
259
260 impl AddAssign<u32> for [<$resource Diff>] {
261 fn add_assign(&mut self, rhs: u32) {
262 *self = *self + rhs;
263 }
264 }
265
266 impl Sub for [<$resource Diff>] {
267 type Output = Self;
268
269 fn sub(self, rhs: Self) -> Self {
270 Self(self.0.saturating_sub(rhs.0))
271 }
272 }
273
274 impl Sub<$resource> for [<$resource Diff>] {
275 type Output = Self;
276
277 fn sub(self, rhs: $resource) -> Self {
278 Self(self.0.saturating_sub_unsigned(rhs.0))
279 }
280 }
281
282 impl Sub<[<$resource Diff>]> for $resource {
283 type Output = Self;
284
285 fn sub(self, rhs: [<$resource Diff>]) -> Self {
286 Self(self.0.saturating_sub_signed(rhs.0))
287 }
288 }
289
290 impl Sub<i32> for [<$resource Diff>] {
291 type Output = Self;
292
293 fn sub(self, rhs: i32) -> Self {
294 Self(self.0.saturating_sub(rhs))
295 }
296 }
297
298 impl Sub<u32> for [<$resource Diff>] {
299 type Output = Self;
300
301 fn sub(self, rhs: u32) -> Self {
302 Self(self.0.saturating_sub_unsigned(rhs))
303 }
304 }
305
306 impl SubAssign for [<$resource Diff>] {
307 fn sub_assign(&mut self, rhs: Self) {
308 *self = *self - rhs;
309 }
310 }
311
312 impl SubAssign<$resource> for [<$resource Diff>] {
313 fn sub_assign(&mut self, rhs: $resource) {
314 *self = *self - rhs;
315 }
316 }
317
318 impl SubAssign<[<$resource Diff>]> for $resource {
319 fn sub_assign(&mut self, rhs: [<$resource Diff>]) {
320 *self = *self - rhs;
321 }
322 }
323
324 impl SubAssign<i32> for [<$resource Diff>] {
325 fn sub_assign(&mut self, rhs: i32) {
326 *self = *self - rhs;
327 }
328 }
329
330 impl SubAssign<u32> for [<$resource Diff>] {
331 fn sub_assign(&mut self, rhs: u32) {
332 *self = *self - rhs;
333 }
334 }
335 )+
336 }
337 }
338}
339
340decl_resource_diff!(Food, Iron, Stone, Wood);