1use crate::error::CamelError;
2use crate::exchange::Exchange;
3use std::sync::Arc;
4use std::time::Duration;
5
6pub type MulticastAggregationFn = Arc<dyn Fn(Exchange, Exchange) -> Exchange + Send + Sync>;
7
8#[derive(Clone, Default)]
9#[non_exhaustive]
10pub enum MulticastStrategy {
11 #[default]
12 LastWins,
13 CollectAll,
14 Original,
15 Custom(MulticastAggregationFn),
16}
17
18impl std::fmt::Debug for MulticastStrategy {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 MulticastStrategy::LastWins => f.write_str("LastWins"),
22 MulticastStrategy::CollectAll => f.write_str("CollectAll"),
23 MulticastStrategy::Original => f.write_str("Original"),
24 MulticastStrategy::Custom(_) => f.write_str("Custom(..)"),
25 }
26 }
27}
28
29#[derive(Clone)]
30pub struct MulticastConfig {
31 pub parallel: bool,
32 pub parallel_limit: Option<usize>,
33 pub stop_on_exception: bool,
34 pub timeout: Option<Duration>,
35 pub aggregation: MulticastStrategy,
36}
37
38impl std::fmt::Debug for MulticastConfig {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 f.debug_struct("MulticastConfig")
41 .field("parallel", &self.parallel)
42 .field("parallel_limit", &self.parallel_limit)
43 .field("stop_on_exception", &self.stop_on_exception)
44 .field("timeout", &self.timeout)
45 .field("aggregation", &self.aggregation)
46 .finish()
47 }
48}
49
50impl MulticastConfig {
51 pub fn new() -> Self {
52 Self {
53 parallel: false,
54 parallel_limit: None,
55 stop_on_exception: false,
56 timeout: None,
57 aggregation: MulticastStrategy::default(),
58 }
59 }
60
61 pub fn parallel(mut self, parallel: bool) -> Self {
62 self.parallel = parallel;
63 self
64 }
65
66 pub fn parallel_limit(mut self, limit: usize) -> Self {
67 self.parallel_limit = Some(limit);
68 self
69 }
70
71 pub fn stop_on_exception(mut self, stop: bool) -> Self {
72 self.stop_on_exception = stop;
73 self
74 }
75
76 pub fn timeout(mut self, duration: Duration) -> Self {
77 self.timeout = Some(duration);
78 self
79 }
80
81 pub fn aggregation(mut self, strategy: MulticastStrategy) -> Self {
82 self.aggregation = strategy;
83 self
84 }
85
86 pub fn validate(&self) -> Result<(), CamelError> {
91 if self.parallel && self.parallel_limit == Some(0) {
92 return Err(CamelError::Config(
93 "multicast parallel_limit must be > 0".to_string(),
94 ));
95 }
96 Ok(())
97 }
98}
99
100impl Default for MulticastConfig {
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109 use std::time::Duration;
110
111 #[test]
112 fn test_multicast_config_defaults() {
113 let config = MulticastConfig::new();
114 assert!(!config.parallel);
115 assert!(config.parallel_limit.is_none());
116 assert!(!config.stop_on_exception);
117 assert!(config.timeout.is_none());
118 assert!(matches!(config.aggregation, MulticastStrategy::LastWins));
119 }
120
121 #[test]
122 fn test_multicast_config_builder() {
123 let config = MulticastConfig::new()
124 .parallel(true)
125 .parallel_limit(4)
126 .stop_on_exception(true)
127 .timeout(Duration::from_millis(500));
128
129 assert!(config.parallel);
130 assert_eq!(config.parallel_limit, Some(4));
131 assert!(config.stop_on_exception);
132 assert_eq!(config.timeout, Some(Duration::from_millis(500)));
133 }
134}