Skip to main content

made_core/value_objects/delivery/
delivery_attempt.rs

1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5/// How many times a delivery has been handed out and come back failed.
6#[derive(
7    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
8)]
9#[serde(transparent)]
10pub struct DeliveryAttempt(u32);
11
12impl DeliveryAttempt {
13    /// A delivery that has not been attempted yet.
14    pub const NONE: Self = Self(0);
15
16    #[must_use]
17    pub const fn value(self) -> u32 {
18        self.0
19    }
20
21    /// One more attempt, saturating rather than wrapping: a counter that
22    /// wrapped would hand an exhausted delivery back to a host forever.
23    #[must_use]
24    pub const fn next(self) -> Self {
25        Self(self.0.saturating_add(1))
26    }
27}
28
29impl fmt::Display for DeliveryAttempt {
30    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
31        write!(formatter, "{}", self.0)
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn counting_saturates_instead_of_wrapping() {
41        assert_eq!(DeliveryAttempt::NONE.next().value(), 1);
42        assert_eq!(DeliveryAttempt(u32::MAX).next().value(), u32::MAX);
43    }
44}