rocketmq_client_rust/consumer/
pull_result.rs1use crate::consumer::pull_status::PullStatus;
16use rocketmq_model::common::message::message_ext::MessageExt;
17
18pub type PullOutcome = rocketmq_model::result::PullOutcome<MessageExt>;
20
21pub type PullOutcomeAdapterError = std::convert::Infallible;
23
24pub struct PullResult {
25 pub(crate) pull_status: PullStatus,
26 pub(crate) next_begin_offset: u64,
27 pub(crate) min_offset: u64,
28 pub(crate) max_offset: u64,
29 pub(crate) msg_found_list: Option<Vec<MessageExt>>,
30}
31
32impl PullResult {
33 pub fn new(
34 pull_status: PullStatus,
35 next_begin_offset: u64,
36 min_offset: u64,
37 max_offset: u64,
38 msg_found_list: Option<Vec<MessageExt>>,
39 ) -> Self {
40 Self {
41 pull_status,
42 next_begin_offset,
43 min_offset,
44 max_offset,
45 msg_found_list,
46 }
47 }
48
49 #[inline]
50 pub fn pull_status(&self) -> &PullStatus {
51 &self.pull_status
52 }
53
54 #[inline]
55 pub fn next_begin_offset(&self) -> u64 {
56 self.next_begin_offset
57 }
58
59 #[inline]
60 pub fn min_offset(&self) -> u64 {
61 self.min_offset
62 }
63
64 #[inline]
65 pub fn max_offset(&self) -> u64 {
66 self.max_offset
67 }
68
69 #[inline]
70 pub fn msg_found_list(&self) -> Option<&[MessageExt]> {
71 self.msg_found_list.as_deref()
72 }
73
74 #[inline]
75 pub fn set_msg_found_list(&mut self, msg_found_list: Option<Vec<MessageExt>>) {
76 self.msg_found_list = msg_found_list;
77 }
78}
79
80impl From<&PullResult> for PullOutcome {
81 fn from(value: &PullResult) -> Self {
82 let messages = value.msg_found_list.clone();
83 Self::new(
84 value.pull_status,
85 value.next_begin_offset,
86 value.min_offset,
87 value.max_offset,
88 messages,
89 )
90 }
91}
92
93impl From<PullOutcome> for PullResult {
94 fn from(value: PullOutcome) -> Self {
95 let pull_status = value.pull_status();
96 let next_begin_offset = value.next_begin_offset();
97 let min_offset = value.min_offset();
98 let max_offset = value.max_offset();
99 let messages = value.into_messages();
100 Self::new(pull_status, next_begin_offset, min_offset, max_offset, messages)
101 }
102}
103
104impl std::fmt::Display for PullResult {
105 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106 write!(
107 f,
108 "PullResult [pullStatus={}, nextBeginOffset={}, minOffset={}, maxOffset={}, msgFoundList={}]",
109 self.pull_status,
110 self.next_begin_offset,
111 self.min_offset,
112 self.max_offset,
113 self.msg_found_list.as_ref().map_or(0, |v| v.len()),
114 )
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn pull_result_display_matches_java_to_string_shape() {
124 let pull_result = PullResult::new(PullStatus::NoNewMsg, 12, 3, 45, None);
125
126 assert_eq!(
127 pull_result.to_string(),
128 "PullResult [pullStatus=NO_NEW_MSG, nextBeginOffset=12, minOffset=3, maxOffset=45, msgFoundList=0]"
129 );
130 }
131
132 #[test]
133 fn pull_outcome_round_trip_preserves_non_empty_owned_messages() {
134 let mut first = MessageExt::default();
135 first.set_queue_offset(10);
136 let mut second = MessageExt::default();
137 second.set_queue_offset(11);
138 let result = PullResult::new(PullStatus::Found, 12, 1, 20, Some(vec![first, second]));
139
140 let round_trip = PullResult::from(PullOutcome::from(&result));
141
142 let offsets = round_trip
143 .msg_found_list()
144 .expect("non-empty messages should remain present")
145 .iter()
146 .map(|message| message.queue_offset)
147 .collect::<Vec<_>>();
148 assert_eq!(offsets, vec![10, 11]);
149 }
150}