camel_api/
dynamic_router.rs1use 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}