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