Skip to main content

made_core/value_objects/ceremony/
step_iteration.rs

1use serde::{Deserialize, Serialize};
2
3use crate::error::DomainError;
4
5pub const MAX_STEP_ITERATIONS: u32 = 1_000;
6
7/// One semantic execution of a ceremony step.
8///
9/// An iteration is distinct from a retry attempt: retries recover the same
10/// execution after failure or lease loss, while a new iteration deliberately
11/// runs successful work again because its declared stop condition is false.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
13#[serde(transparent)]
14pub struct StepIteration(u32);
15
16impl StepIteration {
17    pub const FIRST: Self = Self(1);
18
19    pub fn new(value: u32) -> Result<Self, DomainError> {
20        if value == 0 {
21            return Err(DomainError::MustBeNonZero {
22                field: "step_iteration",
23            });
24        }
25        if value > MAX_STEP_ITERATIONS {
26            return Err(DomainError::OutOfRange {
27                field: "step_iteration",
28                value: f64::from(value),
29                min: 1.0,
30                max: f64::from(MAX_STEP_ITERATIONS),
31            });
32        }
33        Ok(Self(value))
34    }
35
36    pub fn next(self) -> Result<Self, DomainError> {
37        Self::new(self.0.saturating_add(1))
38    }
39
40    #[must_use]
41    pub fn get(self) -> u32 {
42        self.0
43    }
44}
45
46impl Default for StepIteration {
47    fn default() -> Self {
48        Self::FIRST
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn iterations_start_at_one() {
58        assert!(matches!(
59            StepIteration::new(0),
60            Err(DomainError::MustBeNonZero {
61                field: "step_iteration"
62            })
63        ));
64        assert_eq!(StepIteration::FIRST.next().unwrap().get(), 2);
65        assert!(matches!(
66            StepIteration::new(MAX_STEP_ITERATIONS + 1),
67            Err(DomainError::OutOfRange {
68                field: "step_iteration",
69                ..
70            })
71        ));
72    }
73}