Skip to main content

rocketmq_protocol/protocol/static_topic/
topic_queue_mapping_info.rs

1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::HashMap;
16
17use crate::common::wire_constants::METADATA_SCOPE_GLOBAL;
18use cheetah_string::CheetahString;
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}