1use serde::{Deserialize, Serialize};
6
7#[non_exhaustive]
19#[repr(u8)]
20#[derive(
21 Debug,
22 Clone,
23 Copy,
24 PartialEq,
25 Eq,
26 Hash,
27 Serialize,
28 Deserialize,
29 zerompk::ToMessagePack,
30 zerompk::FromMessagePack,
31)]
32#[serde(try_from = "u8", into = "u8")]
33#[msgpack(c_enum)]
34pub enum OpCode {
35 Auth = 0x01,
37 Ping = 0x02,
38 Status = 0x03,
41
42 PointGet = 0x10,
44 PointPut = 0x11,
45 PointDelete = 0x12,
46 VectorSearch = 0x13,
47 RangeScan = 0x14,
48 CrdtRead = 0x15,
49 CrdtApply = 0x16,
50 GraphRagFusion = 0x17,
51 AlterCollectionPolicy = 0x18,
52
53 Sql = 0x20,
55 Ddl = 0x21,
56 Explain = 0x22,
57 CopyFrom = 0x23,
58
59 Set = 0x30,
61 Show = 0x31,
62 Reset = 0x32,
63
64 Begin = 0x40,
66 Commit = 0x41,
67 Rollback = 0x42,
68
69 GraphHop = 0x50,
71 GraphNeighbors = 0x51,
72 GraphPath = 0x52,
73 GraphSubgraph = 0x53,
74 EdgePut = 0x54,
75 EdgeDelete = 0x55,
76 GraphAlgo = 0x56,
77 GraphMatch = 0x57,
78
79 SpatialScan = 0x19,
81
82 TimeseriesScan = 0x1A,
84 TimeseriesIngest = 0x1B,
85
86 TextSearch = 0x60,
88 HybridSearch = 0x61,
89
90 VectorBatchInsert = 0x70,
92 DocumentBatchInsert = 0x71,
93
94 KvScan = 0x72,
96 KvExpire = 0x73,
97 KvPersist = 0x74,
98 KvGetTtl = 0x75,
99 KvBatchGet = 0x76,
100 KvBatchPut = 0x77,
101 KvFieldGet = 0x78,
102 KvFieldSet = 0x79,
103
104 DocumentUpdate = 0x7A,
106 DocumentScan = 0x7B,
107 DocumentUpsert = 0x7C,
108 DocumentBulkUpdate = 0x7D,
109 DocumentBulkDelete = 0x7E,
110
111 VectorInsert = 0x7F,
113 VectorMultiSearch = 0x80,
114 VectorDelete = 0x81,
115
116 ColumnarScan = 0x82,
118 ColumnarInsert = 0x83,
119
120 RecursiveScan = 0x84,
122
123 DocumentTruncate = 0x85,
125 DocumentEstimateCount = 0x86,
126 DocumentInsertSelect = 0x87,
127 DocumentRegister = 0x88,
128 DocumentDropIndex = 0x89,
129
130 KvRegisterIndex = 0x8A,
132 KvDropIndex = 0x8B,
133 KvTruncate = 0x8C,
134
135 VectorSetParams = 0x8D,
137
138 KvIncr = 0x8E,
140 KvIncrFloat = 0x8F,
141 KvCas = 0x90,
142 KvGetSet = 0x91,
143
144 KvRegisterSortedIndex = 0x92,
146 KvDropSortedIndex = 0x93,
147 KvSortedIndexRank = 0x94,
148 KvSortedIndexTopK = 0x95,
149 KvSortedIndexRange = 0x96,
150 KvSortedIndexCount = 0x97,
151 KvSortedIndexScore = 0x98,
152
153 CrdtListInsert = 0x99,
155 CrdtListDelete = 0x9A,
156 CrdtListMove = 0x9B,
157}
158
159impl OpCode {
160 pub fn is_write(&self) -> bool {
162 matches!(
163 self,
164 OpCode::PointPut
165 | OpCode::PointDelete
166 | OpCode::CrdtApply
167 | OpCode::EdgePut
168 | OpCode::EdgeDelete
169 | OpCode::VectorBatchInsert
170 | OpCode::DocumentBatchInsert
171 | OpCode::AlterCollectionPolicy
172 | OpCode::TimeseriesIngest
173 | OpCode::KvExpire
174 | OpCode::KvPersist
175 | OpCode::KvBatchPut
176 | OpCode::KvFieldSet
177 | OpCode::DocumentUpdate
178 | OpCode::DocumentUpsert
179 | OpCode::DocumentBulkUpdate
180 | OpCode::DocumentBulkDelete
181 | OpCode::VectorInsert
182 | OpCode::VectorDelete
183 | OpCode::ColumnarInsert
184 | OpCode::DocumentTruncate
185 | OpCode::DocumentInsertSelect
186 | OpCode::DocumentRegister
187 | OpCode::DocumentDropIndex
188 | OpCode::KvRegisterIndex
189 | OpCode::KvDropIndex
190 | OpCode::KvTruncate
191 | OpCode::VectorSetParams
192 | OpCode::KvIncr
193 | OpCode::KvIncrFloat
194 | OpCode::KvCas
195 | OpCode::KvGetSet
196 | OpCode::KvRegisterSortedIndex
197 | OpCode::KvDropSortedIndex
198 | OpCode::CrdtListInsert
199 | OpCode::CrdtListDelete
200 | OpCode::CrdtListMove
201 )
202 }
203}
204
205impl From<OpCode> for u8 {
206 fn from(op: OpCode) -> u8 {
207 op as u8
208 }
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
213#[error("unknown OpCode byte: 0x{0:02X}")]
214pub struct UnknownOpCode(pub u8);
215
216impl TryFrom<u8> for OpCode {
217 type Error = UnknownOpCode;
218
219 fn try_from(value: u8) -> Result<Self, Self::Error> {
220 match value {
221 0x01 => Ok(OpCode::Auth),
222 0x02 => Ok(OpCode::Ping),
223 0x03 => Ok(OpCode::Status),
224 0x10 => Ok(OpCode::PointGet),
225 0x11 => Ok(OpCode::PointPut),
226 0x12 => Ok(OpCode::PointDelete),
227 0x13 => Ok(OpCode::VectorSearch),
228 0x14 => Ok(OpCode::RangeScan),
229 0x15 => Ok(OpCode::CrdtRead),
230 0x16 => Ok(OpCode::CrdtApply),
231 0x17 => Ok(OpCode::GraphRagFusion),
232 0x18 => Ok(OpCode::AlterCollectionPolicy),
233 0x19 => Ok(OpCode::SpatialScan),
234 0x1A => Ok(OpCode::TimeseriesScan),
235 0x1B => Ok(OpCode::TimeseriesIngest),
236 0x20 => Ok(OpCode::Sql),
237 0x21 => Ok(OpCode::Ddl),
238 0x22 => Ok(OpCode::Explain),
239 0x23 => Ok(OpCode::CopyFrom),
240 0x30 => Ok(OpCode::Set),
241 0x31 => Ok(OpCode::Show),
242 0x32 => Ok(OpCode::Reset),
243 0x40 => Ok(OpCode::Begin),
244 0x41 => Ok(OpCode::Commit),
245 0x42 => Ok(OpCode::Rollback),
246 0x50 => Ok(OpCode::GraphHop),
247 0x51 => Ok(OpCode::GraphNeighbors),
248 0x52 => Ok(OpCode::GraphPath),
249 0x53 => Ok(OpCode::GraphSubgraph),
250 0x54 => Ok(OpCode::EdgePut),
251 0x55 => Ok(OpCode::EdgeDelete),
252 0x56 => Ok(OpCode::GraphAlgo),
253 0x57 => Ok(OpCode::GraphMatch),
254 0x60 => Ok(OpCode::TextSearch),
255 0x61 => Ok(OpCode::HybridSearch),
256 0x70 => Ok(OpCode::VectorBatchInsert),
257 0x71 => Ok(OpCode::DocumentBatchInsert),
258 0x72 => Ok(OpCode::KvScan),
259 0x73 => Ok(OpCode::KvExpire),
260 0x74 => Ok(OpCode::KvPersist),
261 0x75 => Ok(OpCode::KvGetTtl),
262 0x76 => Ok(OpCode::KvBatchGet),
263 0x77 => Ok(OpCode::KvBatchPut),
264 0x78 => Ok(OpCode::KvFieldGet),
265 0x79 => Ok(OpCode::KvFieldSet),
266 0x7A => Ok(OpCode::DocumentUpdate),
267 0x7B => Ok(OpCode::DocumentScan),
268 0x7C => Ok(OpCode::DocumentUpsert),
269 0x7D => Ok(OpCode::DocumentBulkUpdate),
270 0x7E => Ok(OpCode::DocumentBulkDelete),
271 0x7F => Ok(OpCode::VectorInsert),
272 0x80 => Ok(OpCode::VectorMultiSearch),
273 0x81 => Ok(OpCode::VectorDelete),
274 0x82 => Ok(OpCode::ColumnarScan),
275 0x83 => Ok(OpCode::ColumnarInsert),
276 0x84 => Ok(OpCode::RecursiveScan),
277 0x85 => Ok(OpCode::DocumentTruncate),
278 0x86 => Ok(OpCode::DocumentEstimateCount),
279 0x87 => Ok(OpCode::DocumentInsertSelect),
280 0x88 => Ok(OpCode::DocumentRegister),
281 0x89 => Ok(OpCode::DocumentDropIndex),
282 0x8A => Ok(OpCode::KvRegisterIndex),
283 0x8B => Ok(OpCode::KvDropIndex),
284 0x8C => Ok(OpCode::KvTruncate),
285 0x8D => Ok(OpCode::VectorSetParams),
286 0x8E => Ok(OpCode::KvIncr),
287 0x8F => Ok(OpCode::KvIncrFloat),
288 0x90 => Ok(OpCode::KvCas),
289 0x91 => Ok(OpCode::KvGetSet),
290 0x92 => Ok(OpCode::KvRegisterSortedIndex),
291 0x93 => Ok(OpCode::KvDropSortedIndex),
292 0x94 => Ok(OpCode::KvSortedIndexRank),
293 0x95 => Ok(OpCode::KvSortedIndexTopK),
294 0x96 => Ok(OpCode::KvSortedIndexRange),
295 0x97 => Ok(OpCode::KvSortedIndexCount),
296 0x98 => Ok(OpCode::KvSortedIndexScore),
297 0x99 => Ok(OpCode::CrdtListInsert),
298 0x9A => Ok(OpCode::CrdtListDelete),
299 0x9B => Ok(OpCode::CrdtListMove),
300 other => Err(UnknownOpCode(other)),
301 }
302 }
303}
304
305#[non_exhaustive]
312#[repr(u8)]
313#[derive(
314 Debug,
315 Clone,
316 Copy,
317 PartialEq,
318 Eq,
319 Serialize,
320 Deserialize,
321 zerompk::ToMessagePack,
322 zerompk::FromMessagePack,
323)]
324#[msgpack(c_enum)]
325pub enum ResponseStatus {
326 Ok = 0,
328 Partial = 1,
330 Error = 2,
332}
333
334#[cfg(test)]
335mod tests {
336 use super::*;
337
338 #[test]
339 fn crdt_list_opcodes_try_from_u8_roundtrip() {
340 assert_eq!(OpCode::try_from(0x99), Ok(OpCode::CrdtListInsert));
341 assert_eq!(OpCode::try_from(0x9A), Ok(OpCode::CrdtListDelete));
342 assert_eq!(OpCode::try_from(0x9B), Ok(OpCode::CrdtListMove));
343
344 assert_eq!(u8::from(OpCode::CrdtListInsert), 0x99);
345 assert_eq!(u8::from(OpCode::CrdtListDelete), 0x9A);
346 assert_eq!(u8::from(OpCode::CrdtListMove), 0x9B);
347 }
348
349 #[test]
350 fn crdt_list_opcodes_are_writes() {
351 assert!(OpCode::CrdtListInsert.is_write());
352 assert!(OpCode::CrdtListDelete.is_write());
353 assert!(OpCode::CrdtListMove.is_write());
354 }
355}