Skip to main content

nil_core/resources/
diff.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use 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          nil_num::F64Ops,
169        )]
170        #[into(i32, f64)]
171        pub struct [<$resource Diff>](i32);
172
173        impl [<$resource Diff>] {
174          #[inline]
175          pub const fn new(value: i32) -> Self {
176            Self(value)
177          }
178
179          #[inline]
180          pub const fn zero() -> Self {
181            Self(0)
182          }
183        }
184
185        impl PartialEq<i32> for [<$resource Diff>] {
186          fn eq(&self, other: &i32) -> bool {
187            self.0.eq(other)
188          }
189        }
190
191        impl PartialOrd<i32> for [<$resource Diff>] {
192          fn partial_cmp(&self, other: &i32) -> Option<Ordering> {
193            self.0.partial_cmp(other)
194          }
195        }
196
197        impl Add for [<$resource Diff>] {
198          type Output = Self;
199
200          fn add(self, rhs: Self) -> Self {
201            Self(self.0.saturating_add(rhs.0))
202          }
203        }
204
205        impl Add<$resource> for [<$resource Diff>] {
206          type Output = Self;
207
208          fn add(self, rhs: $resource) -> Self {
209            Self(self.0.saturating_add_unsigned(rhs.0))
210          }
211        }
212
213        impl Add<[<$resource Diff>]> for $resource {
214          type Output = Self;
215
216          fn add(self, rhs: [<$resource Diff>]) -> Self {
217            Self(self.0.saturating_add_signed(rhs.0))
218          }
219        }
220
221        impl Add<i32> for [<$resource Diff>] {
222          type Output = Self;
223
224          fn add(self, rhs: i32) -> Self {
225            Self(self.0.saturating_add(rhs))
226          }
227        }
228
229        impl Add<u32> for [<$resource Diff>] {
230          type Output = Self;
231
232          fn add(self, rhs: u32) -> Self {
233            Self(self.0.saturating_add_unsigned(rhs))
234          }
235        }
236
237        impl AddAssign for [<$resource Diff>] {
238          fn add_assign(&mut self, rhs: Self) {
239            *self = *self + rhs;
240          }
241        }
242
243        impl AddAssign<$resource> for [<$resource Diff>] {
244          fn add_assign(&mut self, rhs: $resource) {
245            *self = *self + rhs;
246          }
247        }
248
249        impl AddAssign<[<$resource Diff>]> for $resource {
250          fn add_assign(&mut self, rhs: [<$resource Diff>]) {
251            *self = *self + rhs;
252          }
253        }
254
255        impl AddAssign<i32> for [<$resource Diff>] {
256          fn add_assign(&mut self, rhs: i32) {
257            *self = *self + rhs;
258          }
259        }
260
261        impl AddAssign<u32> for [<$resource Diff>] {
262          fn add_assign(&mut self, rhs: u32) {
263            *self = *self + rhs;
264          }
265        }
266
267        impl Sub for [<$resource Diff>] {
268          type Output = Self;
269
270          fn sub(self, rhs: Self) -> Self {
271            Self(self.0.saturating_sub(rhs.0))
272          }
273        }
274
275        impl Sub<$resource> for [<$resource Diff>] {
276          type Output = Self;
277
278          fn sub(self, rhs: $resource) -> Self {
279            Self(self.0.saturating_sub_unsigned(rhs.0))
280          }
281        }
282
283        impl Sub<[<$resource Diff>]> for $resource {
284          type Output = Self;
285
286          fn sub(self, rhs: [<$resource Diff>]) -> Self {
287            Self(self.0.saturating_sub_signed(rhs.0))
288          }
289        }
290
291        impl Sub<i32> for [<$resource Diff>] {
292          type Output = Self;
293
294          fn sub(self, rhs: i32) -> Self {
295            Self(self.0.saturating_sub(rhs))
296          }
297        }
298
299        impl Sub<u32> for [<$resource Diff>] {
300          type Output = Self;
301
302          fn sub(self, rhs: u32) -> Self {
303            Self(self.0.saturating_sub_unsigned(rhs))
304          }
305        }
306
307        impl SubAssign for [<$resource Diff>] {
308          fn sub_assign(&mut self, rhs: Self) {
309            *self = *self - rhs;
310          }
311        }
312
313        impl SubAssign<$resource> for [<$resource Diff>] {
314          fn sub_assign(&mut self, rhs: $resource) {
315            *self = *self - rhs;
316          }
317        }
318
319        impl SubAssign<[<$resource Diff>]> for $resource {
320          fn sub_assign(&mut self, rhs: [<$resource Diff>]) {
321            *self = *self - rhs;
322          }
323        }
324
325        impl SubAssign<i32> for [<$resource Diff>] {
326          fn sub_assign(&mut self, rhs: i32) {
327            *self = *self - rhs;
328          }
329        }
330
331        impl SubAssign<u32> for [<$resource Diff>] {
332          fn sub_assign(&mut self, rhs: u32) {
333            *self = *self - rhs;
334          }
335        }
336      )+
337    }
338  }
339}
340
341decl_resource_diff!(Food, Iron, Stone, Wood);