Skip to main content

rocketmq_common/common/lite/
offset_option.rs

1use 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/// Enumeration of offset seeking strategies.
99#[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}