Skip to main content

camel_api/
dynamic_router.rs

1use std::sync::Arc;
2use std::time::Duration;
3
4use crate::Exchange;
5
6pub type RouterExpression = Arc<dyn Fn(&Exchange) -> Option<String> + Send + Sync>;
7
8#[derive(Clone)]
9pub struct DynamicRouterConfig {
10    pub expression: RouterExpression,
11    pub uri_delimiter: String,
12    pub cache_size: i32,
13    pub ignore_invalid_endpoints: bool,
14    pub max_iterations: usize,
15    pub timeout: Option<Duration>,
16}
17
18impl DynamicRouterConfig {
19    pub fn new(expression: RouterExpression) -> Self {
20        Self {
21            expression,
22            uri_delimiter: ",".to_string(),
23            cache_size: 1000,
24            ignore_invalid_endpoints: false,
25            max_iterations: 1000,
26            timeout: Some(Duration::from_secs(60)),
27        }
28    }
29
30    pub fn uri_delimiter(mut self, d: impl Into<String>) -> Self {
31        self.uri_delimiter = d.into();
32        self
33    }
34
35    pub fn cache_size(mut self, n: i32) -> Self {
36        self.cache_size = n;
37        self
38    }
39
40    pub fn ignore_invalid_endpoints(mut self, ignore: bool) -> Self {
41        self.ignore_invalid_endpoints = ignore;
42        self
43    }
44
45    pub fn max_iterations(mut self, n: usize) -> Self {
46        self.max_iterations = n;
47        self
48    }
49
50    pub fn timeout(mut self, d: Duration) -> Self {
51        self.timeout = Some(d);
52        self
53    }
54
55    pub fn no_timeout(mut self) -> Self {
56        self.timeout = None;
57        self
58    }
59}
60
61impl std::fmt::Debug for DynamicRouterConfig {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        f.debug_struct("DynamicRouterConfig")
64            .field("uri_delimiter", &self.uri_delimiter)
65            .field("cache_size", &self.cache_size)
66            .field("ignore_invalid_endpoints", &self.ignore_invalid_endpoints)
67            .field("max_iterations", &self.max_iterations)
68            .field("timeout", &self.timeout)
69            .finish()
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use std::sync::Arc;
76    use std::time::Duration;
77
78    use super::*;
79
80    fn noop_expr() -> RouterExpression {
81        Arc::new(|_| None)
82    }
83
84    #[test]
85    fn new_has_defaults() {
86        let cfg = DynamicRouterConfig::new(noop_expr());
87        assert_eq!(cfg.uri_delimiter, ",");
88        assert_eq!(cfg.cache_size, 1000);
89        assert!(!cfg.ignore_invalid_endpoints);
90        assert_eq!(cfg.max_iterations, 1000);
91        assert_eq!(cfg.timeout, Some(Duration::from_secs(60)));
92    }
93
94    #[test]
95    fn builder_chaining() {
96        let cfg = DynamicRouterConfig::new(noop_expr())
97            .uri_delimiter(";")
98            .cache_size(100)
99            .ignore_invalid_endpoints(true)
100            .max_iterations(50)
101            .timeout(Duration::from_secs(10));
102        assert_eq!(cfg.uri_delimiter, ";");
103        assert_eq!(cfg.cache_size, 100);
104        assert!(cfg.ignore_invalid_endpoints);
105        assert_eq!(cfg.max_iterations, 50);
106        assert_eq!(cfg.timeout, Some(Duration::from_secs(10)));
107    }
108
109    #[test]
110    fn no_timeout_clears() {
111        let cfg = DynamicRouterConfig::new(noop_expr()).no_timeout();
112        assert!(cfg.timeout.is_none());
113    }
114
115    #[test]
116    fn debug_format_contains_fields() {
117        let cfg = DynamicRouterConfig::new(noop_expr());
118        let debug = format!("{cfg:?}");
119        assert!(debug.contains("DynamicRouterConfig"));
120        assert!(debug.contains("uri_delimiter"));
121        assert!(debug.contains("cache_size"));
122    }
123
124    #[test]
125    fn clone_preserves_values() {
126        let cfg = DynamicRouterConfig::new(noop_expr())
127            .uri_delimiter("|")
128            .cache_size(42);
129        let cloned = cfg.clone();
130        assert_eq!(cloned.uri_delimiter, "|");
131        assert_eq!(cloned.cache_size, 42);
132    }
133}