rocketmq_remoting/protocol/body/topic_info_wrapper/
topic_config_wrapper.rs1use std::collections::HashMap;
16
17use cheetah_string::CheetahString;
18use dashmap::DashMap;
19use rocketmq_common::common::config::TopicConfig;
20use rocketmq_rust::ArcMut;
21use serde::Deserialize;
22use serde::Serialize;
23
24use crate::protocol::static_topic::topic_queue_mapping_detail::TopicQueueMappingDetail;
25use crate::protocol::static_topic::topic_queue_mapping_info::TopicQueueMappingInfo;
26use crate::protocol::DataVersion;
27
28#[derive(Debug, Clone, Serialize, Deserialize, Default)]
29pub struct TopicConfigAndMappingSerializeWrapper {
30 #[serde(rename = "topicQueueMappingInfoMap")]
31 pub topic_queue_mapping_info_map: DashMap<CheetahString , ArcMut<TopicQueueMappingInfo>>,
32
33 #[serde(rename = "topicQueueMappingDetailMap")]
34 pub topic_queue_mapping_detail_map: DashMap<CheetahString , ArcMut<TopicQueueMappingDetail>>,
35
36 #[serde(rename = "mappingDataVersion")]
37 pub mapping_data_version: DataVersion,
38
39 #[serde(flatten)]
40 pub topic_config_serialize_wrapper: TopicConfigSerializeWrapper,
41}
42
43impl TopicConfigAndMappingSerializeWrapper {
44 pub fn topic_queue_mapping_info_map(&self) -> &DashMap<CheetahString, ArcMut<TopicQueueMappingInfo>> {
45 &self.topic_queue_mapping_info_map
46 }
47
48 pub fn topic_queue_mapping_detail_map(
49 &self,
50 ) -> &DashMap<CheetahString , ArcMut<TopicQueueMappingDetail>> {
51 &self.topic_queue_mapping_detail_map
52 }
53
54 pub fn mapping_data_version(&self) -> &DataVersion {
55 &self.mapping_data_version
56 }
57 pub fn topic_config_serialize_wrapper(&self) -> &TopicConfigSerializeWrapper {
58 &self.topic_config_serialize_wrapper
59 }
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
63pub struct TopicConfigSerializeWrapper {
64 #[serde(rename = "topicConfigTable")]
65 pub topic_config_table: HashMap<CheetahString, TopicConfig>,
66 #[serde(rename = "dataVersion")]
67 pub data_version: DataVersion,
68}
69
70impl TopicConfigSerializeWrapper {
71 pub fn topic_config_table(&self) -> &HashMap<CheetahString, TopicConfig> {
72 &self.topic_config_table
73 }
74
75 pub fn data_version(&self) -> &DataVersion {
76 &self.data_version
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn topic_config_and_mapping_serialize_wrapper_default() {
86 let wrapper = TopicConfigAndMappingSerializeWrapper::default();
87 assert!(wrapper.topic_queue_mapping_info_map.is_empty());
88 assert!(wrapper.topic_queue_mapping_detail_map.is_empty());
89 assert_eq!(wrapper.mapping_data_version, DataVersion::new());
90 assert!(wrapper.topic_config_serialize_wrapper().topic_config_table().is_empty());
91 assert_eq!(
92 wrapper.topic_config_serialize_wrapper().data_version(),
93 &DataVersion::new()
94 );
95 }
96
97 #[test]
98 fn topic_config_and_mapping_serialize_wrapper_getters() {
99 let mut wrapper = TopicConfigAndMappingSerializeWrapper::default();
100 let _topic_config = TopicConfig::default();
101 let topic_queue_mapping_info = ArcMut::new(TopicQueueMappingInfo::default());
102 let topic_queue_mapping_detail = ArcMut::<TopicQueueMappingDetail>::default();
103 let data_version = DataVersion::default();
104
105 let topic_config_serialize_wrapper = TopicConfigSerializeWrapper::default();
106 wrapper.topic_config_serialize_wrapper = topic_config_serialize_wrapper.clone();
107 wrapper
108 .topic_queue_mapping_info_map
109 .insert("test".into(), topic_queue_mapping_info.clone());
110 wrapper
111 .topic_queue_mapping_detail_map
112 .insert("test".into(), topic_queue_mapping_detail.clone());
113
114 assert_eq!(wrapper.mapping_data_version(), &data_version);
115 assert_eq!(
116 wrapper.topic_config_serialize_wrapper(),
117 &topic_config_serialize_wrapper
118 );
119 }
120
121 #[test]
122 fn topic_config_serialize_wrapper_methods() {
123 let mut wrapper = TopicConfigSerializeWrapper::default();
124 let topic_config = TopicConfig::default();
125 wrapper
126 .topic_config_table
127 .insert("test_topic".into(), topic_config.clone());
128 let data_version = DataVersion::default();
129 wrapper.data_version = data_version.clone();
130
131 assert_eq!(
132 wrapper
133 .topic_config_table()
134 .get(&CheetahString::from_static_str("test_topic")),
135 Some(&topic_config)
136 );
137 assert_eq!(wrapper.data_version(), &data_version);
138 }
139
140 fn create_topic_config(name: &str) -> (CheetahString, TopicConfig) {
141 (CheetahString::from(name), TopicConfig::default())
142 }
143
144 #[test]
145 fn test_default_initialization() {
146 let wrapper = TopicConfigSerializeWrapper::default();
147 assert!(wrapper.topic_config_table.is_empty());
148 assert_eq!(wrapper.data_version, DataVersion::default());
149 }
150
151 #[test]
152 fn test_clone_trait() {
153 let mut wrapper = TopicConfigSerializeWrapper::default();
154 let (k, v) = create_topic_config("topic_a");
155 wrapper.topic_config_table.insert(k.clone(), v.clone());
156
157 let cloned = wrapper.clone();
158
159 assert_eq!(wrapper, cloned);
160 assert_eq!(cloned.topic_config_table.get(&k), Some(&v));
161 }
162
163 #[test]
164 fn test_partial_eq_identical() {
165 let mut w1 = TopicConfigSerializeWrapper::default();
166 let mut w2 = TopicConfigSerializeWrapper::default();
167
168 let (k, v) = create_topic_config("topic_eq");
169
170 w1.topic_config_table.insert(k.clone(), v.clone());
171 w2.topic_config_table.insert(k, v);
172
173 assert_eq!(w1, w2);
174 }
175
176 #[test]
177 fn test_partial_eq_different() {
178 let mut w1 = TopicConfigSerializeWrapper::default();
179 let mut w2 = TopicConfigSerializeWrapper::default();
180
181 let (k1, v1) = create_topic_config("topic1");
182 let (k2, v2) = create_topic_config("topic2");
183
184 w1.topic_config_table.insert(k1, v1);
185 w2.topic_config_table.insert(k2, v2);
186
187 assert_ne!(w1, w2);
188 }
189
190 #[test]
191 fn test_getters() {
192 let mut wrapper = TopicConfigSerializeWrapper::default();
193
194 let (k, v) = create_topic_config("topic_getter");
195 wrapper.topic_config_table.insert(k.clone(), v.clone());
196
197 let dv = DataVersion::default();
198 wrapper.data_version = dv.clone();
199
200 assert_eq!(wrapper.topic_config_table().get(&k), Some(&v));
201 assert_eq!(wrapper.data_version(), &dv);
202 }
203
204 #[test]
205 fn test_empty_topic_config_table() {
206 let wrapper = TopicConfigSerializeWrapper::default();
207 assert!(wrapper.topic_config_table().is_empty());
208 }
209
210 #[test]
211 fn test_single_topic_config() {
212 let mut wrapper = TopicConfigSerializeWrapper::default();
213 let (k, v) = create_topic_config("single_topic");
214
215 wrapper.topic_config_table.insert(k.clone(), v.clone());
216
217 assert_eq!(wrapper.topic_config_table().len(), 1);
218 assert_eq!(wrapper.topic_config_table().get(&k), Some(&v));
219 }
220
221 #[test]
222 fn test_multiple_topic_configs() {
223 let mut wrapper = TopicConfigSerializeWrapper::default();
224
225 for i in 0..5 {
226 let name = format!("topic_{i}");
227 let (k, v) = create_topic_config(&name);
228 wrapper.topic_config_table.insert(k, v);
229 }
230
231 assert_eq!(wrapper.topic_config_table().len(), 5);
232 }
233
234 #[test]
235 fn test_data_version_behavior() {
236 let mut wrapper = TopicConfigSerializeWrapper::default();
237 let dv = DataVersion::default();
238
239 wrapper.data_version = dv.clone();
240
241 assert_eq!(wrapper.data_version(), &dv);
242 }
243
244 #[test]
245 fn test_json_serialization_field_names() {
246 let mut wrapper = TopicConfigSerializeWrapper::default();
247 let (k, v) = create_topic_config("serde_topic");
248
249 wrapper.topic_config_table.insert(k, v);
250
251 let json = serde_json::to_string(&wrapper).unwrap();
252
253 assert!(json.contains("topicConfigTable"));
254 assert!(json.contains("dataVersion"));
255 }
256
257 #[test]
258 fn test_json_deserialization_field_names() {
259 let json = r#"
260 {
261 "topicConfigTable": {},
262 "dataVersion": {
263 "stateVersion": 0,
264 "timestamp": 0,
265 "counter": 0
266 }
267 }
268 "#;
269
270 let wrapper: TopicConfigSerializeWrapper = serde_json::from_str(json).unwrap();
271
272 assert!(wrapper.topic_config_table.is_empty());
273 }
274
275 #[test]
276 fn test_serde_roundtrip() {
277 let mut wrapper = TopicConfigSerializeWrapper::default();
278
279 let (k1, v1) = create_topic_config("topic_round_1");
280 let (k2, v2) = create_topic_config("topic_round_2");
281
282 wrapper.topic_config_table.insert(k1, v1);
283 wrapper.topic_config_table.insert(k2, v2);
284
285 let json = serde_json::to_string(&wrapper).unwrap();
286 let decoded: TopicConfigSerializeWrapper = serde_json::from_str(&json).unwrap();
287
288 assert_eq!(wrapper, decoded);
289 }
290
291 #[test]
292 fn test_debug_trait_output() {
293 let wrapper = TopicConfigSerializeWrapper::default();
294 let debug_str = format!("{:?}", wrapper);
295
296 assert!(debug_str.contains("TopicConfigSerializeWrapper"));
297 }
298
299 #[test]
300 fn test_create_with_populated_fields() {
301 let mut table = HashMap::new();
302 let (k, v) = create_topic_config("populated_topic");
303
304 table.insert(k.clone(), v.clone());
305
306 let dv = DataVersion::default();
307
308 let wrapper = TopicConfigSerializeWrapper {
309 topic_config_table: table,
310 data_version: dv.clone(),
311 };
312
313 assert_eq!(wrapper.topic_config_table().get(&k), Some(&v));
314 assert_eq!(wrapper.data_version(), &dv);
315 }
316}