Skip to main content

camel_api/
loop_eip.rs

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