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