rocketmq_common/common/lite/
offset_option.rs1use serde::Deserialize;
2use serde::Serialize;
3use std::fmt;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
6#[serde(rename_all = "camelCase")]
7#[non_exhaustive]
8pub struct OffsetOption {
9 #[serde(rename = "type")]
10 pub type_: OffsetOptionType,
11 pub value: i64,
12}
13
14impl OffsetOption {
15 pub const POLICY_LAST_VALUE: i64 = 0;
16 pub const POLICY_MIN_VALUE: i64 = 1;
17 pub const POLICY_MAX_VALUE: i64 = 2;
18
19 #[must_use]
20 #[inline]
21 pub const fn new(type_: OffsetOptionType, value: i64) -> Self {
22 Self { type_, value }
23 }
24
25 #[must_use]
26 #[inline]
27 pub const fn policy(policy: i64) -> Self {
28 debug_assert!(
29 policy == Self::POLICY_LAST_VALUE || policy == Self::POLICY_MIN_VALUE || policy == Self::POLICY_MAX_VALUE,
30 "Invalid policy value"
31 );
32 Self {
33 type_: OffsetOptionType::Policy,
34 value: policy,
35 }
36 }
37
38 #[must_use]
39 #[inline]
40 pub const fn offset(value: i64) -> Self {
41 Self {
42 type_: OffsetOptionType::Offset,
43 value,
44 }
45 }
46
47 #[must_use]
48 #[inline]
49 pub const fn tail_n(n: i64) -> Self {
50 Self {
51 type_: OffsetOptionType::TailN,
52 value: n,
53 }
54 }
55
56 #[must_use]
57 #[inline]
58 pub const fn timestamp(timestamp: i64) -> Self {
59 Self {
60 type_: OffsetOptionType::Timestamp,
61 value: timestamp,
62 }
63 }
64
65 #[inline]
66 pub const fn type_(&self) -> OffsetOptionType {
67 self.type_
68 }
69
70 #[inline]
71 pub fn set_type(&mut self, type_: OffsetOptionType) {
72 self.type_ = type_;
73 }
74
75 #[inline]
76 pub const fn value(&self) -> i64 {
77 self.value
78 }
79
80 #[inline]
81 pub fn set_value(&mut self, value: i64) {
82 self.value = value;
83 }
84}
85
86impl Default for OffsetOption {
87 fn default() -> Self {
88 Self::policy(Self::POLICY_LAST_VALUE)
89 }
90}
91
92impl fmt::Display for OffsetOption {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 write!(f, "OffsetOption {{ type: {}, value: {} }}", self.type_, self.value)
95 }
96}
97
98#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
100#[non_exhaustive]
101pub enum OffsetOptionType {
102 Policy = 0,
103 Offset = 1,
104 TailN = 2,
105 Timestamp = 3,
106}
107
108impl OffsetOptionType {
109 #[must_use]
110 #[inline]
111 pub const fn from_i32(value: i32) -> Option<Self> {
112 match value {
113 0 => Some(Self::Policy),
114 1 => Some(Self::Offset),
115 2 => Some(Self::TailN),
116 3 => Some(Self::Timestamp),
117 _ => None,
118 }
119 }
120
121 #[must_use]
122 #[inline]
123 pub const fn as_i32(self) -> i32 {
124 self as i32
125 }
126}
127
128impl fmt::Display for OffsetOptionType {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 match self {
131 Self::Policy => f.write_str("POLICY"),
132 Self::Offset => f.write_str("OFFSET"),
133 Self::TailN => f.write_str("TAIL_N"),
134 Self::Timestamp => f.write_str("TIMESTAMP"),
135 }
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn offset_option_constructors() {
145 let option = OffsetOption::new(OffsetOptionType::Policy, OffsetOption::POLICY_MIN_VALUE);
146 assert_eq!(option.type_(), OffsetOptionType::Policy);
147 assert_eq!(option.value(), OffsetOption::POLICY_MIN_VALUE);
148
149 let policy = OffsetOption::policy(OffsetOption::POLICY_MAX_VALUE);
150 assert_eq!(policy.type_(), OffsetOptionType::Policy);
151 assert_eq!(policy.value(), OffsetOption::POLICY_MAX_VALUE);
152
153 let offset = OffsetOption::offset(100);
154 assert_eq!(offset.type_(), OffsetOptionType::Offset);
155 assert_eq!(offset.value(), 100);
156
157 let tail_n = OffsetOption::tail_n(10);
158 assert_eq!(tail_n.type_(), OffsetOptionType::TailN);
159 assert_eq!(tail_n.value(), 10);
160
161 let timestamp = OffsetOption::timestamp(123456789);
162 assert_eq!(timestamp.type_(), OffsetOptionType::Timestamp);
163 assert_eq!(timestamp.value(), 123456789);
164 }
165
166 #[test]
167 fn offset_option_setters() {
168 let mut option = OffsetOption::default();
169 assert_eq!(option.type_(), OffsetOptionType::Policy);
170 assert_eq!(option.value(), OffsetOption::POLICY_LAST_VALUE);
171
172 option.set_type(OffsetOptionType::TailN);
173 option.set_value(5);
174 assert_eq!(option.type_(), OffsetOptionType::TailN);
175 assert_eq!(option.value(), 5);
176 }
177
178 #[test]
179 fn offset_option_display() {
180 let option = OffsetOption::offset(100);
181 let format = format!("{}", option);
182 let expected = "OffsetOption { type: OFFSET, value: 100 }";
183 assert_eq!(format, expected);
184 }
185
186 #[test]
187 fn offset_option_serde() {
188 let option = OffsetOption::offset(100);
189 let json = serde_json::to_string(&option).unwrap();
190 let expected = r#"{"type":"Offset","value":100}"#;
191 assert_eq!(json, expected);
192 let decoded: OffsetOption = serde_json::from_str(&json).unwrap();
193 assert_eq!(option, decoded);
194 }
195
196 #[test]
197 fn offset_option_type_conversion() {
198 assert_eq!(OffsetOptionType::from_i32(0), Some(OffsetOptionType::Policy));
199 assert_eq!(OffsetOptionType::from_i32(1), Some(OffsetOptionType::Offset));
200 assert_eq!(OffsetOptionType::from_i32(2), Some(OffsetOptionType::TailN));
201 assert_eq!(OffsetOptionType::from_i32(3), Some(OffsetOptionType::Timestamp));
202 assert_eq!(OffsetOptionType::from_i32(4), None);
203
204 assert_eq!(OffsetOptionType::Policy.as_i32(), 0);
205 assert_eq!(OffsetOptionType::Offset.as_i32(), 1);
206 assert_eq!(OffsetOptionType::TailN.as_i32(), 2);
207 assert_eq!(OffsetOptionType::Timestamp.as_i32(), 3);
208 }
209
210 #[test]
211 fn offset_option_type_display() {
212 assert_eq!(format!("{}", OffsetOptionType::Policy), "POLICY");
213 assert_eq!(format!("{}", OffsetOptionType::Offset), "OFFSET");
214 assert_eq!(format!("{}", OffsetOptionType::TailN), "TAIL_N");
215 assert_eq!(format!("{}", OffsetOptionType::Timestamp), "TIMESTAMP");
216 }
217}