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 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);