Skip to main content

server/domain/scoreboard/
points.rs

1use serde::{Deserialize, Serialize};
2
3/// Represents a point value in the game.
4///
5/// Wraps a `usize` and provides ordering and comparison operations.
6#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
7#[repr(transparent)]
8#[serde(transparent)]
9pub struct Points(usize);
10
11impl Points {
12    /// Returns the internal numeric value of the points.
13    #[must_use]
14    pub fn value(&self) -> usize {
15        self.0
16    }
17}
18
19impl From<usize> for Points {
20    fn from(value: usize) -> Self {
21        Self(value)
22    }
23}
24
25impl std::ops::Add<Points> for Points {
26    type Output = Points;
27
28    fn add(self, rhs: Points) -> Self::Output {
29        Points::from(self.0 + rhs.0)
30    }
31}
32
33impl std::ops::AddAssign for Points {
34    fn add_assign(&mut self, rhs: Self) {
35        self.0 += rhs.0
36    }
37}
38
39impl std::iter::Sum<Self> for Points {
40    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
41        iter.map(|v| v.0).sum::<usize>().into()
42    }
43}
44
45impl std::fmt::Display for Points {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        self.0.fmt(f)
48    }
49}
50
51#[cfg(test)]
52mod test {
53    use super::*;
54
55    #[test]
56    fn points_will_be_displayed_as_numeric_value() {
57        let points = Points::from(42);
58        assert_eq!(points.to_string(), "42");
59    }
60}