rocketmq_remoting/protocol/static_topic/
topic_queue_mapping_info.rs1use std::collections::HashMap;
16
17use cheetah_string::CheetahString;
18use rocketmq_common::common::mix_all::METADATA_SCOPE_GLOBAL;
19use serde::Deserialize;
20use serde::Serialize;
21
22use crate::protocol::static_topic::i32_key_map_serde;
23
24#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
25pub struct TopicQueueMappingInfo {
26 pub topic: Option<CheetahString>,
27 pub scope: Option<CheetahString>,
28 #[serde(rename = "totalQueues")]
29 pub total_queues: i32,
30 pub bname: Option<CheetahString>,
31 pub epoch: i64,
32 pub dirty: bool,
33 #[serde(rename = "currIdMap")]
34 #[serde(default, deserialize_with = "i32_key_map_serde::deserialize_optional_i32_key_map")]
35 pub curr_id_map: Option<HashMap<i32, i32>>,
36}
37
38impl Default for TopicQueueMappingInfo {
39 fn default() -> Self {
40 Self {
41 topic: None,
42 scope: Some(CheetahString::from_static_str(METADATA_SCOPE_GLOBAL)),
43 total_queues: 0,
44 bname: None,
45 epoch: 0,
46 dirty: false,
47 curr_id_map: None,
48 }
49 }
50}
51
52impl TopicQueueMappingInfo {
53 pub fn new(topic: CheetahString, total_queues: i32, bname: CheetahString, epoch: i64) -> Self {
54 Self {
55 topic: Some(topic),
56 scope: Some(CheetahString::from_static_str(METADATA_SCOPE_GLOBAL)),
57 total_queues,
58 bname: Some(bname),
59 epoch,
60 dirty: false,
61 curr_id_map: None,
62 }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn topic_queue_mapping_info_default() {
72 let info = TopicQueueMappingInfo::default();
73 assert!(info.topic.is_none());
74 assert_eq!(
75 info.scope.unwrap(),
76 CheetahString::from_static_str(METADATA_SCOPE_GLOBAL)
77 );
78 assert_eq!(info.total_queues, 0);
79 assert!(info.bname.is_none());
80 assert_eq!(info.epoch, 0);
81 assert!(!info.dirty);
82 assert!(info.curr_id_map.is_none());
83 }
84
85 #[test]
86 fn topic_queue_mapping_info_new() {
87 let topic = CheetahString::from("test_topic");
88 let bname = CheetahString::from("broker_a");
89 let info = TopicQueueMappingInfo::new(topic.clone(), 8, bname.clone(), 12345);
90 assert_eq!(info.topic.unwrap(), topic);
91 assert_eq!(
92 info.scope.unwrap(),
93 CheetahString::from_static_str(METADATA_SCOPE_GLOBAL)
94 );
95 assert_eq!(info.total_queues, 8);
96 assert_eq!(info.bname.unwrap(), bname);
97 assert_eq!(info.epoch, 12345);
98 assert!(!info.dirty);
99 assert!(info.curr_id_map.is_none());
100 }
101
102 #[test]
103 fn topic_queue_mapping_info_serde() {
104 let mut curr_id_map = HashMap::new();
105 curr_id_map.insert(1, 100);
106
107 let info = TopicQueueMappingInfo {
108 topic: Some(CheetahString::from("test_topic")),
109 scope: Some(CheetahString::from("custom_scope")),
110 total_queues: 16,
111 bname: Some(CheetahString::from("broker_b")),
112 epoch: 67890,
113 dirty: true,
114 curr_id_map: Some(curr_id_map),
115 };
116
117 let json = serde_json::to_string(&info).unwrap();
118 let expected = r#"{"topic":"test_topic","scope":"custom_scope","totalQueues":16,"bname":"broker_b","epoch":67890,"dirty":true,"currIdMap":{"1":100}}"#;
119 assert_eq!(json, expected);
120
121 let deserialized: TopicQueueMappingInfo = serde_json::from_str(&json).unwrap();
122 assert_eq!(info, deserialized);
123 }
124}