1use bytes::Bytes;
2
3#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
5pub enum Op {
6 Get,
7 Gets,
8 Gat,
9 Gats,
10 Set,
11 Add,
12 Replace,
13 Append,
14 Prepend,
15 Cas,
16 Delete,
17 Flush,
18 Incr,
19 Decr,
20 Touch,
21 Stats,
22 Version,
23 SaslListMechs,
24 SaslAuth,
25 SaslStep,
26 Quit,
27 MetaGet,
28 MetaSet,
29 MetaDelete,
30 MetaArithmetic,
31 MetaDebug,
32 MetaNoop,
33 Noop,
34 Unknown,
35}
36
37#[derive(Debug, Clone, Copy, Eq, PartialEq)]
39pub enum Protocol {
40 Ascii,
41 Meta,
42 Binary,
43}
44
45#[derive(Debug, Clone, Copy, Eq, PartialEq)]
47pub enum ReplyMode {
48 Always,
50 SuppressSuccess,
52 SuppressMiss,
54 QuietBuffered,
56}
57
58#[derive(Debug, Clone)]
60pub struct Request {
61 pub op: Op,
62 pub key: Option<Bytes>,
63 pub keys: Vec<Bytes>,
64 pub value: Option<Bytes>,
65 pub flags: Option<u32>,
66 pub exptime: Option<i64>,
67 pub cas: Option<u64>,
68 pub delta: Option<u64>,
69 pub initial: Option<u64>,
70 pub meta: Option<MetaFlags>,
71}
72
73impl Request {
74 pub fn new(op: Op) -> Self {
75 Self {
76 op,
77 key: None,
78 keys: Vec::new(),
79 value: None,
80 flags: None,
81 exptime: None,
82 cas: None,
83 delta: None,
84 initial: None,
85 meta: None,
86 }
87 }
88}
89
90#[derive(Debug, Clone, Copy)]
92pub struct RequestMeta {
93 pub protocol: Protocol,
94 pub reply: ReplyMode,
95 pub opaque: Option<u32>,
96 pub return_key: bool,
97 pub opcode: u8,
98}
99
100impl RequestMeta {
101 pub fn ascii() -> Self {
102 Self {
103 protocol: Protocol::Ascii,
104 reply: ReplyMode::Always,
105 opaque: None,
106 return_key: false,
107 opcode: 0,
108 }
109 }
110}
111
112#[derive(Debug, Clone)]
114pub struct MetaFlags {
115 pub ordered: Vec<MetaFlag>,
116 pub mask: u64,
117}
118
119impl MetaFlags {
120 pub fn new(ordered: Vec<MetaFlag>) -> Self {
121 let mut mask = 0u64;
122 for flag in &ordered {
123 if let Some(bit) = flag_bit(flag.code) {
124 mask |= 1u64 << bit;
125 }
126 }
127 Self { ordered, mask }
128 }
129
130 pub fn has(&self, code: u8) -> bool {
131 if let Some(bit) = flag_bit(code)
132 && (self.mask & (1u64 << bit)) != 0
133 {
134 return true;
135 }
136 self.ordered.iter().any(|flag| flag.code == code)
137 }
138
139 pub fn token(&self, code: u8) -> Option<&Bytes> {
140 self.ordered
141 .iter()
142 .find(|flag| flag.code == code)
143 .and_then(|flag| flag.token.as_ref())
144 }
145}
146
147fn flag_bit(code: u8) -> Option<u64> {
148 match code {
149 b'a'..=b'z' => Some((code - b'a') as u64),
150 b'A'..=b'Z' => Some((26 + (code - b'A')) as u64),
151 b'0'..=b'9' => Some((52 + (code - b'0')) as u64),
152 _ => None,
153 }
154}
155
156#[derive(Debug, Clone)]
158pub struct MetaFlag {
159 pub code: u8,
160 pub token: Option<Bytes>,
161}
162
163#[derive(Debug, Clone, Copy, Eq, PartialEq)]
165pub enum MetaCode {
166 Hd,
167 Va,
168 En,
169 Ns,
170 Ex,
171 Nf,
172}
173
174impl MetaCode {
175 pub fn as_bytes(self) -> &'static [u8] {
176 match self {
177 MetaCode::Hd => b"HD",
178 MetaCode::Va => b"VA",
179 MetaCode::En => b"EN",
180 MetaCode::Ns => b"NS",
181 MetaCode::Ex => b"EX",
182 MetaCode::Nf => b"NF",
183 }
184 }
185
186 pub fn is_success(self) -> bool {
187 matches!(self, MetaCode::Hd | MetaCode::Va)
188 }
189
190 pub fn is_miss(self) -> bool {
191 matches!(self, MetaCode::En)
192 }
193}
194
195#[derive(Debug, Clone)]
197pub struct MetaResponse {
198 pub code: MetaCode,
199 pub value: Option<Bytes>,
200 pub cas: Option<u64>,
201 pub flags: Option<u32>,
202 pub ttl: Option<i64>,
203 pub size: Option<usize>,
204 pub hit: Option<bool>,
205 pub last_access: Option<u64>,
206 pub extra: MetaExtra,
207}
208
209impl MetaResponse {
210 pub fn new(code: MetaCode) -> Self {
211 Self {
212 code,
213 value: None,
214 cas: None,
215 flags: None,
216 ttl: None,
217 size: None,
218 hit: None,
219 last_access: None,
220 extra: MetaExtra::default(),
221 }
222 }
223}
224
225#[derive(Debug, Clone, Default)]
227pub struct MetaExtra {
228 pub won: Option<WinState>,
229 pub stale: bool,
230}
231
232#[derive(Debug, Clone, Copy, Eq, PartialEq)]
233pub enum WinState {
234 Won,
235 AlreadyWon,
236}
237
238#[derive(Debug, Clone)]
240pub struct ValueEntry {
241 pub key: Bytes,
242 pub value: Bytes,
243 pub flags: u32,
244 pub cas: Option<u64>,
245}
246
247#[derive(Debug, Clone)]
249pub struct StatLine {
250 pub key: Bytes,
251 pub value: Bytes,
252}
253
254pub trait ValuesStream {
256 fn next(&mut self) -> Option<ValueEntry>;
257}
258
259pub trait StatsStream {
261 fn next(&mut self) -> Option<StatLine>;
262}