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