1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub struct StringPair<'a> {
5 pub key: &'a [u8],
6 pub value: &'a [u8],
7}
8
9impl<'a> StringPair<'a> {
10 #[inline]
11 pub const fn new(key: &'a [u8], value: &'a [u8]) -> Self {
12 Self { key, value }
13 }
14
15 #[inline]
16 pub const fn key(&self) -> &'a [u8] {
17 self.key
18 }
19
20 #[inline]
21 pub const fn value(&self) -> &'a [u8] {
22 self.value
23 }
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
29pub enum StringSetType {
30 #[default]
31 None,
32 Nx,
33 Xx,
34 IfEq,
35 IfNe,
36 IfDeq,
37 IfDne,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
43pub struct StringSet<'a> {
44 pub expire: u64,
45 pub set_type: StringSetType,
46 pub get: bool,
47 pub keep_ttl: bool,
48 pub cmp_value: Option<&'a [u8]>,
49}
50
51impl<'a> StringSet<'a> {
52 #[inline]
55 pub const fn is_fast_path(&self) -> bool {
56 matches!(self.set_type, StringSetType::None)
57 && !self.get
58 && !self.keep_ttl
59 && self.cmp_value.is_none()
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
66pub enum Set<'a> {
67 Ex(u64),
68 Px(u64),
69 ExAt(u64),
70 PxAt(u64),
71 KeepTtl,
72 Nx,
73 Xx,
74 IfEq(&'a [u8]),
75 IfNe(&'a [u8]),
76 IfDeq(&'a [u8]),
77 IfDne(&'a [u8]),
78 Get,
79}
80
81impl<'a> Set<'a> {
82 pub fn parse_options(options: impl IntoIterator<Item = Set<'a>>, now_ms: u64) -> StringSet<'a> {
85 let mut set_type = StringSetType::None;
86 let mut get = false;
87 let mut keep_ttl = false;
88 let mut expire = 0u64;
89 let mut cmp_value: Option<&'a [u8]> = None;
90
91 for opt in options {
92 match opt {
93 Set::Ex(sec) => {
94 expire = now_ms.saturating_add(sec.saturating_mul(1000));
95 keep_ttl = false;
96 }
97 Set::Px(ms) => {
98 expire = now_ms.saturating_add(ms);
99 keep_ttl = false;
100 }
101 Set::ExAt(sec) => {
102 expire = sec.saturating_mul(1000);
103 keep_ttl = false;
104 }
105 Set::PxAt(ms) => {
106 expire = ms;
107 keep_ttl = false;
108 }
109 Set::KeepTtl => {
110 keep_ttl = true;
111 expire = 0;
112 }
113 Set::Nx => {
114 set_type = StringSetType::Nx;
115 cmp_value = None;
116 }
117 Set::Xx => {
118 set_type = StringSetType::Xx;
119 cmp_value = None;
120 }
121 Set::IfEq(expected) => {
122 set_type = StringSetType::IfEq;
123 cmp_value = Some(expected);
124 }
125 Set::IfNe(expected) => {
126 set_type = StringSetType::IfNe;
127 cmp_value = Some(expected);
128 }
129 Set::IfDeq(expected) => {
130 set_type = StringSetType::IfDeq;
131 cmp_value = Some(expected);
132 }
133 Set::IfDne(expected) => {
134 set_type = StringSetType::IfDne;
135 cmp_value = Some(expected);
136 }
137 Set::Get => get = true,
138 }
139 }
140
141 StringSet {
142 expire,
143 set_type,
144 get,
145 keep_ttl,
146 cmp_value,
147 }
148 }
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq)]
154pub enum GetEx {
155 Ex(u64),
156 Px(u64),
157 ExAt(u64),
158 PxAt(u64),
159 Persist,
160}
161
162impl GetEx {
163 #[inline]
166 pub const fn compute_expire(&self, now_ms: u64) -> u64 {
167 match *self {
168 Self::Persist => 0,
169 Self::Ex(sec) => now_ms.saturating_add(sec.saturating_mul(1000)),
170 Self::Px(ms) => now_ms.saturating_add(ms),
171 Self::ExAt(sec) => sec.saturating_mul(1000),
172 Self::PxAt(ms) => ms,
173 }
174 }
175}
176
177#[derive(Debug, Clone, PartialEq, Eq, Default)]
180pub enum DelEx<'a> {
181 #[default]
182 None,
183 IfEq(&'a [u8]),
184 IfNe(&'a [u8]),
185 IfDeq(&'a [u8]),
186 IfDne(&'a [u8]),
187}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
192pub struct StringMSet {
193 pub expire: u64,
194 pub set_type: StringSetType,
195 pub keep_ttl: bool,
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
201pub enum StringLCSType {
202 #[default]
203 None,
204 Len,
205 Idx,
206}
207
208#[derive(Debug, Clone, Copy, PartialEq, Eq)]
211pub struct StringLCS {
212 pub lcs_type: StringLCSType,
213 pub min_match_len: i64,
214}
215
216impl Default for StringLCS {
217 fn default() -> Self {
218 Self {
219 lcs_type: StringLCSType::None,
220 min_match_len: 0,
221 }
222 }
223}
224
225#[derive(Debug, Clone, Copy, PartialEq, Eq)]
228pub enum Lcs {
229 Len,
230 Idx,
231 WithMatchLen,
232 MinMatchLen(i64),
233}
234
235impl Lcs {
236 pub fn parse_options(options: impl IntoIterator<Item = Lcs>) -> StringLCS {
237 let mut lcs_type = StringLCSType::None;
238 let mut min_match_len = 0;
239 for opt in options {
240 match opt {
241 Lcs::Len => lcs_type = StringLCSType::Len,
242 Lcs::Idx | Lcs::WithMatchLen => lcs_type = StringLCSType::Idx,
243 Lcs::MinMatchLen(len) => {
244 lcs_type = StringLCSType::Idx;
245 min_match_len = len;
246 }
247 }
248 }
249 StringLCS {
250 lcs_type,
251 min_match_len,
252 }
253 }
254}
255
256impl From<&[Lcs]> for StringLCS {
257 fn from(options: &[Lcs]) -> Self {
258 Lcs::parse_options(options.iter().copied())
259 }
260}
261
262#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
265pub struct StringLCSRange {
266 pub start: u32,
267 pub end: u32,
268}
269
270#[derive(Debug, Clone, Copy, PartialEq, Eq)]
273pub struct StringLCSMatchedRange {
274 pub a: StringLCSRange,
275 pub b: StringLCSRange,
276 pub match_len: u32,
277}
278
279impl StringLCSMatchedRange {
280 #[inline]
281 pub const fn new(a_start: u32, a_end: u32, b_start: u32, b_end: u32, match_len: u32) -> Self {
282 Self {
283 a: StringLCSRange {
284 start: a_start,
285 end: a_end,
286 },
287 b: StringLCSRange {
288 start: b_start,
289 end: b_end,
290 },
291 match_len,
292 }
293 }
294
295 #[inline]
296 pub const fn a_start(&self) -> u32 {
297 self.a.start
298 }
299
300 #[inline]
301 pub const fn a_end(&self) -> u32 {
302 self.a.end
303 }
304
305 #[inline]
306 pub const fn b_start(&self) -> u32 {
307 self.b.start
308 }
309
310 #[inline]
311 pub const fn b_end(&self) -> u32 {
312 self.b.end
313 }
314}
315
316#[derive(Debug, Clone, PartialEq, Eq, Default)]
319pub struct StringLCSIdxResult {
320 pub matches: Vec<StringLCSMatchedRange>,
321 pub len: u32,
322}
323
324#[derive(Debug, Clone, PartialEq, Eq)]
327pub enum StringLCSResult {
328 Str(String),
329 Len(u32),
330 Idx(StringLCSIdxResult),
331}