Skip to main content

server/domain/types/card/
value.rs

1/// Point value of a card.
2///
3/// Standard mapping:
4/// - Ace → 1
5/// - 2–10 → face value
6/// - Jack / Queen / King → 10
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
8#[repr(transparent)]
9pub struct Value(usize);
10
11impl Value {
12    /// Returns the underlying numeric value.
13    #[inline(always)]
14    #[must_use]
15    pub fn value(&self) -> usize {
16        self.0
17    }
18}
19
20impl From<usize> for Value {
21    fn from(value: usize) -> Self {
22        Self(value)
23    }
24}
25
26impl std::ops::Add for Value {
27    type Output = Self;
28
29    fn add(self, rhs: Self) -> Self::Output {
30        Self(self.0 + rhs.0)
31    }
32}
33
34impl std::iter::Sum<Self> for Value {
35    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
36        iter.map(|v| v.0).sum::<usize>().into()
37    }
38}
39
40impl std::fmt::Display for Value {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        self.0.fmt(f)
43    }
44}
45
46#[cfg(test)]
47#[coverage(off)]
48mod test {
49    use super::*;
50
51    #[test]
52    fn array_of_values_can_be_summed() {
53        let values = Vec::from([3, 4].map(Value::from));
54        let sum: Value = values.into_iter().sum();
55        assert_eq!(sum, Value::from(7));
56    }
57
58    #[test]
59    fn value_can_be_displayed() {
60        let value = Value::from(42);
61        assert_eq!(value.to_string(), "42".to_string());
62    }
63}