nil_core/resources/
gold.rs1use crate::market::fee::MarketFee;
5use crate::resources::Resources;
6use derive_more::Display;
7use nil_num::impl_mul_ceil;
8use nil_num::mul_ceil::MulCeil;
9use nil_util::{ConstDeref, F64Math};
10use serde::{Deserialize, Serialize};
11use std::iter::Sum;
12use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
13
14#[derive(Copy, Debug, Display, Deserialize, Serialize, ConstDeref, F64Math)]
16#[derive_const(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
17#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
18pub struct Gold(u32);
19
20impl Gold {
21 pub const MIN: Self = Self::new(0);
22 pub const MAX: Self = Self::new(u32::MAX);
23
24 #[inline]
25 pub const fn new(value: u32) -> Self {
26 Self(value)
27 }
28
29 #[inline]
30 pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
31 self.0.checked_sub(rhs.0).map(Self::new)
32 }
33}
34
35impl_mul_ceil!(Gold);
36
37const impl From<u32> for Gold {
38 fn from(value: u32) -> Self {
39 Self::new(value)
40 }
41}
42
43const impl From<Gold> for u32 {
44 fn from(value: Gold) -> Self {
45 value.0
46 }
47}
48
49const impl From<f64> for Gold {
50 fn from(value: f64) -> Self {
51 debug_assert!(value.is_finite());
52 debug_assert!(value >= 0.0);
53 Self(value.trunc() as u32)
54 }
55}
56
57const impl From<Gold> for f64 {
58 fn from(value: Gold) -> Self {
59 f64::from(value.0)
60 }
61}
62
63const impl From<Resources> for Gold {
64 fn from(value: Resources) -> Self {
65 let Resources { food, iron, stone, wood } = value;
68
69 Gold(0)
70 .add(Gold::from(food))
71 .add(Gold::from(iron))
72 .add(Gold::from(stone))
73 .add(Gold::from(wood))
74 }
75}
76
77const impl Add for Gold {
78 type Output = Gold;
79
80 fn add(self, rhs: Gold) -> Self::Output {
81 Self::new(self.0.saturating_add(rhs.0))
82 }
83}
84
85const impl Add<Resources> for Gold {
86 type Output = Gold;
87
88 fn add(self, rhs: Resources) -> Self::Output {
89 self + Gold::from(rhs)
90 }
91}
92
93const impl AddAssign for Gold {
94 fn add_assign(&mut self, rhs: Gold) {
95 *self = *self + rhs;
96 }
97}
98
99const impl AddAssign<Resources> for Gold {
100 fn add_assign(&mut self, rhs: Resources) {
101 *self = *self + rhs;
102 }
103}
104
105const impl Sub for Gold {
106 type Output = Gold;
107
108 fn sub(self, rhs: Gold) -> Self::Output {
109 Self::new(self.0.saturating_sub(rhs.0))
110 }
111}
112
113const impl SubAssign for Gold {
114 fn sub_assign(&mut self, rhs: Gold) {
115 *self = *self - rhs;
116 }
117}
118
119const impl Mul<u32> for Gold {
120 type Output = Gold;
121
122 fn mul(self, rhs: u32) -> Self::Output {
123 Self::new(self.0.saturating_mul(rhs))
124 }
125}
126
127const impl Mul<MarketFee> for Gold {
128 type Output = Gold;
129
130 fn mul(self, rhs: MarketFee) -> Self::Output {
131 Self::from(self.mul_ceil(*rhs))
132 }
133}
134
135impl Sum<Gold> for Gold {
136 fn sum<I>(iter: I) -> Self
137 where
138 I: Iterator<Item = Gold>,
139 {
140 iter.fold(Gold::default(), |acc, gold| acc + gold)
141 }
142}
143
144impl Sum<Resources> for Gold {
145 fn sum<I>(iter: I) -> Self
146 where
147 I: Iterator<Item = Resources>,
148 {
149 iter.fold(Gold::default(), |acc, resources| acc + resources)
150 }
151}