Skip to main content

made_core/value_objects/delivery/
loop_limits.rs

1use serde::{Deserialize, Serialize};
2
3use super::LoopRoundLimit;
4
5/// How long an integrator's loop may go round before it stops itself.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub struct LoopLimits {
8    #[serde(default, skip_serializing_if = "Option::is_none")]
9    max_rounds: Option<LoopRoundLimit>,
10    no_progress_rounds: LoopRoundLimit,
11}
12
13impl LoopLimits {
14    #[must_use]
15    pub const fn new(
16        max_rounds: Option<LoopRoundLimit>,
17        no_progress_rounds: LoopRoundLimit,
18    ) -> Self {
19        Self {
20            max_rounds,
21            no_progress_rounds,
22        }
23    }
24
25    /// A ceiling on rounds, when the caller set one.
26    #[must_use]
27    pub const fn max_rounds(self) -> Option<LoopRoundLimit> {
28        self.max_rounds
29    }
30
31    /// How many rounds with nothing new before the loop declares itself stuck.
32    #[must_use]
33    pub const fn no_progress_rounds(self) -> LoopRoundLimit {
34        self.no_progress_rounds
35    }
36}
37
38impl Default for LoopLimits {
39    fn default() -> Self {
40        Self {
41            max_rounds: None,
42            no_progress_rounds: LoopRoundLimit::default_without_progress(),
43        }
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn the_default_is_unbounded_rounds_and_three_without_progress() {
53        let limits = LoopLimits::default();
54        assert!(limits.max_rounds().is_none());
55        assert_eq!(limits.no_progress_rounds().value(), 3);
56    }
57}