nil_core/resources/
workforce.rs1use crate::city::stability::Stability;
5use crate::infrastructure::building::Building;
6use crate::infrastructure::building::level::BuildingLevel;
7use crate::world::config::WorldConfig;
8use derive_more::Display;
9use nil_num::impl_mul_ceil;
10use nil_num::mul_ceil::MulCeil;
11use nil_util::{ConstDeref, F64Math};
12use serde::{Deserialize, Serialize};
13use std::cmp::Ordering;
14use std::num::NonZeroU32;
15use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
16
17#[derive(Copy, Debug, Display, Deserialize, Serialize, ConstDeref, F64Math)]
24#[derive_const(Clone, PartialEq, Eq, PartialOrd, Ord)]
25#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
26pub struct Workforce(u32);
27
28impl Workforce {
29 #[inline]
30 pub const fn new(value: u32) -> Self {
31 Self(value)
32 }
33}
34
35impl const From<u32> for Workforce {
36 fn from(value: u32) -> Self {
37 Workforce::new(value)
38 }
39}
40
41impl const From<Workforce> for u32 {
42 fn from(value: Workforce) -> Self {
43 value.0
44 }
45}
46
47impl const From<Workforce> for f64 {
48 fn from(value: Workforce) -> Self {
49 f64::from(value.0)
50 }
51}
52
53impl const From<BuildingLevel> for Workforce {
54 fn from(value: BuildingLevel) -> Self {
55 Workforce(u32::from(value))
56 }
57}
58
59impl const From<f64> for Workforce {
60 fn from(value: f64) -> Self {
61 debug_assert!(value >= 0.0);
62 debug_assert!(value.is_finite());
63 Self::new(value.ceil() as u32)
64 }
65}
66
67impl const PartialEq<u32> for Workforce {
68 fn eq(&self, other: &u32) -> bool {
69 self.0.eq(other)
70 }
71}
72
73impl const PartialOrd<u32> for Workforce {
74 fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
75 self.0.partial_cmp(other)
76 }
77}
78
79impl const Add for Workforce {
80 type Output = Workforce;
81
82 fn add(self, rhs: Self) -> Self::Output {
83 Self(self.0.saturating_add(rhs.0))
84 }
85}
86
87impl const AddAssign for Workforce {
88 fn add_assign(&mut self, rhs: Self) {
89 *self = *self + rhs;
90 }
91}
92
93impl const Sub for Workforce {
94 type Output = Workforce;
95
96 fn sub(self, rhs: Self) -> Self::Output {
97 Self(self.0.saturating_sub(rhs.0))
98 }
99}
100
101impl const SubAssign for Workforce {
102 fn sub_assign(&mut self, rhs: Self) {
103 *self = *self - rhs;
104 }
105}
106
107impl const Mul for Workforce {
108 type Output = Workforce;
109
110 fn mul(self, rhs: Workforce) -> Self::Output {
111 Self(self.0.saturating_mul(rhs.0))
112 }
113}
114
115impl const Mul<u32> for Workforce {
116 type Output = Workforce;
117
118 fn mul(self, rhs: u32) -> Self::Output {
119 Self(self.0.saturating_mul(rhs))
120 }
121}
122
123impl const Mul<NonZeroU32> for Workforce {
124 type Output = Workforce;
125
126 fn mul(self, rhs: NonZeroU32) -> Self::Output {
127 self * rhs.get()
128 }
129}
130
131impl const Mul<Stability> for Workforce {
132 type Output = Workforce;
133
134 fn mul(self, rhs: Stability) -> Self::Output {
135 Self::from(self.mul_ceil(*rhs))
136 }
137}
138
139impl const MulAssign for Workforce {
140 fn mul_assign(&mut self, rhs: Self) {
141 *self = *self * rhs;
142 }
143}
144
145impl const MulAssign<Stability> for Workforce {
146 fn mul_assign(&mut self, rhs: Stability) {
147 *self = *self * rhs;
148 }
149}
150
151impl_mul_ceil!(Workforce);
152
153pub trait WorkforceSource: Building {
155 fn workforce(&self, config: &WorldConfig) -> Workforce {
156 Workforce::from(f64::from(self.level()) * config.speed())
157 }
158}