Skip to main content

camel_api/
loop_eip.rs

1use crate::filter::FilterPredicate;
2
3/// How the loop terminates.
4#[derive(Clone)]
5#[non_exhaustive]
6pub enum LoopMode {
7    /// Fixed iteration count.
8    Count(usize),
9    /// While a runtime predicate evaluates to true.
10    While(FilterPredicate),
11}
12
13impl std::fmt::Debug for LoopMode {
14    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15        match self {
16            LoopMode::Count(n) => write!(f, "Count({n})"),
17            LoopMode::While(_) => write!(f, "While(<predicate>)"),
18        }
19    }
20}
21
22#[derive(Clone, Debug)]
23pub struct LoopConfig {
24    pub mode: LoopMode,
25    pub max_iterations: usize,
26}
27
28impl LoopConfig {
29    pub fn new(mode: LoopMode) -> Self {
30        Self {
31            mode,
32            max_iterations: MAX_LOOP_ITERATIONS,
33        }
34    }
35
36    pub fn with_max_iterations(mut self, max: usize) -> Self {
37        self.max_iterations = max;
38        self
39    }
40
41    pub fn mode_name(&self) -> &'static str {
42        match &self.mode {
43            LoopMode::Count(_) => "count",
44            LoopMode::While(_) => "while",
45        }
46    }
47}
48
49/// Maximum iterations for while-mode loops. Prevents infinite loops.
50pub const MAX_LOOP_ITERATIONS: usize = 10_000;
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    fn always_true() -> FilterPredicate {
57        FilterPredicate::new(|_| true)
58    }
59
60    #[test]
61    fn loop_config_new_count() {
62        let cfg = LoopConfig::new(LoopMode::Count(5));
63        assert_eq!(cfg.mode_name(), "count");
64    }
65
66    #[test]
67    fn loop_config_new_while() {
68        let cfg = LoopConfig::new(LoopMode::While(always_true()));
69        assert_eq!(cfg.mode_name(), "while");
70    }
71
72    #[test]
73    fn loop_mode_debug_count() {
74        let mode = LoopMode::Count(3);
75        assert_eq!(format!("{mode:?}"), "Count(3)");
76    }
77
78    #[test]
79    fn loop_mode_debug_while() {
80        let mode = LoopMode::While(always_true());
81        assert_eq!(format!("{mode:?}"), "While(<predicate>)");
82    }
83
84    #[test]
85    fn loop_mode_clone_count() {
86        let mode = LoopMode::Count(10);
87        let cloned = mode.clone();
88        assert_eq!(format!("{cloned:?}"), "Count(10)");
89    }
90
91    #[test]
92    fn loop_config_clone() {
93        let cfg = LoopConfig::new(LoopMode::Count(2));
94        let cloned = cfg.clone();
95        assert_eq!(cloned.mode_name(), "count");
96    }
97
98    #[test]
99    fn max_loop_iterations_value() {
100        assert_eq!(MAX_LOOP_ITERATIONS, 10_000);
101    }
102
103    #[test]
104    fn loop_config_default_max_iterations() {
105        let cfg = LoopConfig::new(LoopMode::Count(5));
106        assert_eq!(cfg.max_iterations, MAX_LOOP_ITERATIONS);
107    }
108
109    #[test]
110    fn loop_config_with_max_iterations() {
111        let cfg = LoopConfig::new(LoopMode::Count(5)).with_max_iterations(500_000);
112        assert_eq!(cfg.max_iterations, 500_000);
113    }
114}