rocketmq_remoting/protocol/header/
query_message_request_header.rs1use cheetah_string::CheetahString;
16use rocketmq_macros::RequestHeaderCodecV2;
17use serde::Deserialize;
18use serde::Serialize;
19
20use crate::rpc::topic_request_header::TopicRequestHeader;
21
22#[derive(Debug, Clone, Serialize, Deserialize, RequestHeaderCodecV2)]
23#[serde(rename_all = "camelCase")]
24pub struct QueryMessageRequestHeader {
25 #[required]
26 pub topic: CheetahString,
27
28 #[required]
29 pub key: CheetahString,
30
31 #[required]
32 pub max_num: i32,
33
34 #[required]
35 pub begin_timestamp: i64,
36
37 #[required]
38 pub end_timestamp: i64,
39
40 #[serde(flatten)]
41 pub topic_request_header: Option<TopicRequestHeader>,
42}
43
44#[cfg(test)]
45mod query_message_request_header_tests {
46 use std::collections::HashMap;
47
48 use super::*;
49 use crate::protocol::command_custom_header::CommandCustomHeader;
50 use crate::protocol::command_custom_header::FromMap;
51
52 #[test]
53 fn creating_from_map_with_all_fields_populates_struct_correctly() {
54 let mut map = HashMap::new();
55 map.insert("topic".into(), "test_topic".into());
56 map.insert("key".into(), "test_key".into());
57 map.insert("maxNum".into(), "10".into());
58 map.insert("beginTimestamp".into(), "1000".into());
59 map.insert("endTimestamp".into(), "2000".into());
60
61 let header: QueryMessageRequestHeader = <QueryMessageRequestHeader as FromMap>::from(&map).unwrap();
62
63 assert_eq!(header.topic, "test_topic");
64 assert_eq!(header.key, "test_key");
65 assert_eq!(header.max_num, 10);
66 assert_eq!(header.begin_timestamp, 1000);
67 assert_eq!(header.end_timestamp, 2000);
68 }
69
70 #[test]
71 fn creating_from_map_missing_optional_fields_still_succeeds() {
72 let mut map = HashMap::new();
73 map.insert("topic".into(), "test_topic".into());
74 map.insert("key".into(), "test_key".into());
75 map.insert("maxNum".into(), "10".into());
76 map.insert("beginTimestamp".into(), "1000".into());
77 map.insert("endTimestamp".into(), "2000".into());
78
79 let header: QueryMessageRequestHeader = <QueryMessageRequestHeader as FromMap>::from(&map).unwrap();
80
81 assert_eq!(header.topic, "test_topic");
82 assert_eq!(header.key, "test_key");
83 assert_eq!(header.max_num, 10);
84 }
85
86 #[test]
87 fn creating_from_map_with_invalid_number_fields_returns_none() {
88 let mut map = HashMap::new();
89 map.insert("topic".into(), "test_topic".into());
90 map.insert("key".into(), "test_key".into());
91 map.insert("maxNum".into(), "invalid".into());
92
93 let header: Result<QueryMessageRequestHeader, rocketmq_error::RocketMQError> =
94 <QueryMessageRequestHeader as FromMap>::from(&map);
95
96 assert!(header.is_err());
97 }
98
99 #[test]
100 fn to_map_includes_all_fields() {
101 let header = QueryMessageRequestHeader {
102 topic: "test_topic".into(),
103 key: "test_key".into(),
104 max_num: 10,
105 begin_timestamp: 1000,
106 end_timestamp: 2000,
107 topic_request_header: None,
108 };
109
110 let map: HashMap<CheetahString, CheetahString> = header.to_map().unwrap();
111
112 assert_eq!(map.get("topic").unwrap(), "test_topic");
113 assert_eq!(map.get("key").unwrap(), "test_key");
114 assert_eq!(map.get("maxNum").unwrap(), "10");
115 assert_eq!(map.get("beginTimestamp").unwrap(), "1000");
116 assert_eq!(map.get("endTimestamp").unwrap(), "2000");
117 }
118
119 #[test]
120 fn to_map_with_topic_request_header_includes_nested_fields() {
121 let topic_request_header = TopicRequestHeader::default();
122 let header = QueryMessageRequestHeader {
123 topic: "test_topic".into(),
124 key: "test_key".into(),
125 max_num: 10,
126 begin_timestamp: 1000,
127 end_timestamp: 2000,
128 topic_request_header: Some(topic_request_header),
129 };
130
131 let map = header.to_map().unwrap();
132
133 assert!(!map.contains_key("nestedField"));
137 }
138}