rocketmq_model/common/entity/
topic_group.rs1use std::hash::Hash;
16use std::hash::Hasher;
17
18use cheetah_string::CheetahString;
19use serde::Deserialize;
20use serde::Serialize;
21
22#[derive(Debug, Clone, Serialize, Deserialize, Default, Eq)]
23pub struct TopicGroup {
24 #[serde(default)]
25 pub topic: CheetahString,
26
27 #[serde(default)]
28 pub group: CheetahString,
29}
30
31impl TopicGroup {
32 pub fn from_parts(topic: CheetahString, group: CheetahString) -> Self {
33 Self { topic, group }
34 }
35
36 #[must_use]
37 pub fn topic(&self) -> &CheetahString {
38 &self.topic
39 }
40
41 pub fn with_topic(&mut self, topic: CheetahString) -> &mut Self {
42 self.topic = topic;
43 self
44 }
45
46 #[must_use]
47 pub fn group(&self) -> &CheetahString {
48 &self.group
49 }
50
51 pub fn with_group(&mut self, group: CheetahString) -> &mut Self {
52 self.group = group;
53 self
54 }
55}
56
57impl PartialEq for TopicGroup {
58 fn eq(&self, other: &Self) -> bool {
59 self.topic == other.topic && self.group == other.group
60 }
61}
62
63impl Hash for TopicGroup {
64 fn hash<H: Hasher>(&self, state: &mut H) {
65 self.topic.hash(state);
66 self.group.hash(state);
67 }
68}
69
70impl std::fmt::Display for TopicGroup {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 write!(f, "TopicGroup{{topic='{}', group='{}'}}", self.topic, self.group)
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn topic_group_default() {
82 let tg = TopicGroup::default();
83 assert!(tg.topic().is_empty());
84 assert!(tg.group().is_empty());
85 }
86
87 #[test]
88 fn topic_group_from_parts() {
89 let tg = TopicGroup::from_parts("topic".into(), "group".into());
90 assert_eq!(tg.topic(), "topic");
91 assert_eq!(tg.group(), "group");
92 }
93
94 #[test]
95 fn topic_group_with_methods() {
96 let mut tg = TopicGroup::default();
97 tg.with_topic("topic".into()).with_group("group".into());
98 assert_eq!(tg.topic(), "topic");
99 assert_eq!(tg.group(), "group");
100 }
101
102 #[test]
103 fn topic_group_partial_eq_and_hash() {
104 let tg1 = TopicGroup::from_parts("topic".into(), "group".into());
105 let tg2 = TopicGroup::from_parts("topic".into(), "group".into());
106 let tg3 = TopicGroup::from_parts("topic2".into(), "group".into());
107 assert_eq!(tg1, tg2);
108 assert_ne!(tg1, tg3);
109
110 use std::collections::hash_map::DefaultHasher;
111 let mut hasher1 = DefaultHasher::new();
112 tg1.hash(&mut hasher1);
113 let mut hasher2 = DefaultHasher::new();
114 tg2.hash(&mut hasher2);
115 assert_eq!(hasher1.finish(), hasher2.finish());
116 }
117
118 #[test]
119 fn topic_group_display() {
120 let tg = TopicGroup::from_parts("topic".into(), "group".into());
121 let display = format!("{}", tg);
122 let expected = "TopicGroup{topic='topic', group='group'}";
123 assert_eq!(display, expected);
124 }
125
126 #[test]
127 fn topic_group_serde() {
128 let tg = TopicGroup::from_parts("topic".into(), "group".into());
129 let json = serde_json::to_string(&tg).unwrap();
130 let expected = r#"{"topic":"topic","group":"group"}"#;
131 assert_eq!(json, expected);
132 let decoded: TopicGroup = serde_json::from_str(&json).unwrap();
133 assert_eq!(decoded, tg);
134 }
135}