Skip to main content

couchbase_core/memdx/
opcode.rs

1/*
2 *
3 *  * Copyright (c) 2025 Couchbase, Inc.
4 *  *
5 *  * Licensed under the Apache License, Version 2.0 (the "License");
6 *  * you may not use this file except in compliance with the License.
7 *  * You may obtain a copy of the License at
8 *  *
9 *  *    http://www.apache.org/licenses/LICENSE-2.0
10 *  *
11 *  * Unless required by applicable law or agreed to in writing, software
12 *  * distributed under the License is distributed on an "AS IS" BASIS,
13 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  * See the License for the specific language governing permissions and
15 *  * limitations under the License.
16 *
17 */
18
19use std::fmt::{Display, Formatter};
20
21use crate::memdx::error::Error;
22
23#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
24#[non_exhaustive]
25pub enum OpCode {
26    Get,
27    Set,
28    Add,
29    Replace,
30    Delete,
31    Increment,
32    Decrement,
33    Noop,
34    Touch,
35    GAT,
36    Append,
37    Prepend,
38    Hello,
39    GetClusterConfig,
40    GetCollectionId,
41    SubDocGet,
42    SubDocExists,
43    SubDocDictAdd,
44    SubDocDictSet,
45    SubDocDelete,
46    SubDocReplace,
47    SubDocArrayPushLast,
48    SubDocArrayPushFirst,
49    SubDocArrayInsert,
50    SubDocArrayAddUnique,
51    SubDocCounter,
52    SubDocMultiLookup,
53    SubDocMultiMutation,
54    SubDocGetCount,
55    SubDocReplaceBodyWithXattr,
56    GetErrorMap,
57    SelectBucket,
58    GetLocked,
59    UnlockKey,
60    GetMeta,
61    SASLAuth,
62    SASLListMechs,
63    SASLStep,
64    Unknown(u8),
65}
66
67impl From<OpCode> for u8 {
68    fn from(value: OpCode) -> Self {
69        match value {
70            OpCode::Get => 0x00,
71            OpCode::Set => 0x01,
72            OpCode::Add => 0x02,
73            OpCode::Replace => 0x03,
74            OpCode::Delete => 0x04,
75            OpCode::Increment => 0x05,
76            OpCode::Decrement => 0x06,
77            OpCode::Noop => 0x0a,
78            OpCode::Append => 0x0e,
79            OpCode::Prepend => 0x0f,
80            OpCode::Touch => 0x1c,
81            OpCode::GAT => 0x1d,
82            OpCode::Hello => 0x1f,
83            OpCode::SASLListMechs => 0x20,
84            OpCode::SASLAuth => 0x21,
85            OpCode::SASLStep => 0x22,
86            OpCode::SelectBucket => 0x89,
87            OpCode::GetLocked => 0x94,
88            OpCode::UnlockKey => 0x95,
89            OpCode::GetMeta => 0xa0,
90            OpCode::GetClusterConfig => 0xb5,
91            OpCode::GetCollectionId => 0xbb,
92            OpCode::SubDocGet => 0xc5,
93            OpCode::SubDocExists => 0xc6,
94            OpCode::SubDocDictAdd => 0xc7,
95            OpCode::SubDocDictSet => 0xc8,
96            OpCode::SubDocDelete => 0xc9,
97            OpCode::SubDocReplace => 0xca,
98            OpCode::SubDocArrayPushLast => 0xcb,
99            OpCode::SubDocArrayPushFirst => 0xcc,
100            OpCode::SubDocArrayInsert => 0xcd,
101            OpCode::SubDocArrayAddUnique => 0xce,
102            OpCode::SubDocCounter => 0xcf,
103            OpCode::SubDocMultiLookup => 0xd0,
104            OpCode::SubDocMultiMutation => 0xd1,
105            OpCode::SubDocGetCount => 0xd2,
106            OpCode::SubDocReplaceBodyWithXattr => 0xd3,
107            OpCode::GetErrorMap => 0xfe,
108            OpCode::Unknown(code) => code,
109        }
110    }
111}
112
113impl TryFrom<u8> for OpCode {
114    type Error = Error;
115
116    fn try_from(value: u8) -> Result<Self, Self::Error> {
117        let code = match value {
118            0x00 => OpCode::Get,
119            0x01 => OpCode::Set,
120            0x02 => OpCode::Add,
121            0x03 => OpCode::Replace,
122            0x04 => OpCode::Delete,
123            0x05 => OpCode::Increment,
124            0x06 => OpCode::Decrement,
125            0x0a => OpCode::Noop,
126            0x0e => OpCode::Append,
127            0x0f => OpCode::Prepend,
128            0x1c => OpCode::Touch,
129            0x1d => OpCode::GAT,
130            0x1f => OpCode::Hello,
131            0x20 => OpCode::SASLListMechs,
132            0x21 => OpCode::SASLAuth,
133            0x22 => OpCode::SASLStep,
134            0x89 => OpCode::SelectBucket,
135            0x94 => OpCode::GetLocked,
136            0x95 => OpCode::UnlockKey,
137            0xb5 => OpCode::GetClusterConfig,
138            0xbb => OpCode::GetCollectionId,
139            0xc5 => OpCode::SubDocGet,
140            0xc6 => OpCode::SubDocExists,
141            0xc7 => OpCode::SubDocDictAdd,
142            0xc8 => OpCode::SubDocDictSet,
143            0xc9 => OpCode::SubDocDelete,
144            0xca => OpCode::SubDocReplace,
145            0xcb => OpCode::SubDocArrayPushLast,
146            0xcc => OpCode::SubDocArrayPushFirst,
147            0xcd => OpCode::SubDocArrayInsert,
148            0xce => OpCode::SubDocArrayAddUnique,
149            0xcf => OpCode::SubDocCounter,
150            0xd0 => OpCode::SubDocMultiLookup,
151            0xd1 => OpCode::SubDocMultiMutation,
152            0xd2 => OpCode::SubDocGetCount,
153            0xd3 => OpCode::SubDocReplaceBodyWithXattr,
154            0xfe => OpCode::GetErrorMap,
155            _ => OpCode::Unknown(value),
156        };
157
158        Ok(code)
159    }
160}
161
162impl Display for OpCode {
163    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
164        let txt = match self {
165            OpCode::Get => "Get",
166            OpCode::Set => "Set",
167            OpCode::Add => "Add",
168            OpCode::Replace => "Replace",
169            OpCode::Delete => "Delete",
170            OpCode::Increment => "Increment",
171            OpCode::Decrement => "Decrement",
172            OpCode::Noop => "Noop",
173            OpCode::Append => "Append",
174            OpCode::Prepend => "Prepend",
175            OpCode::Touch => "Touch",
176            OpCode::GAT => "GAT",
177            OpCode::GetMeta => "Get meta",
178            OpCode::Hello => "Hello",
179            OpCode::GetClusterConfig => "Get cluster config",
180            OpCode::GetCollectionId => "Get collection id",
181            OpCode::GetErrorMap => "Get error map",
182            OpCode::SelectBucket => "Select bucket",
183            OpCode::GetLocked => "Get locked",
184            OpCode::UnlockKey => "Unlock key",
185            OpCode::SASLAuth => "SASL auth",
186            OpCode::SASLListMechs => "SASL list mechanisms",
187            OpCode::SASLStep => "SASL step",
188            OpCode::SubDocGet => "SubDoc get",
189            OpCode::SubDocExists => "SubDoc exists",
190            OpCode::SubDocDictAdd => "SubDoc dict add",
191            OpCode::SubDocDictSet => "SubDoc dict set",
192            OpCode::SubDocDelete => "SubDoc delete",
193            OpCode::SubDocReplace => "SubDoc replace",
194            OpCode::SubDocArrayPushLast => "SubDoc array push last",
195            OpCode::SubDocArrayPushFirst => "SubDoc array push first",
196            OpCode::SubDocArrayInsert => "SubDoc array insert",
197            OpCode::SubDocArrayAddUnique => "SubDoc array add unique",
198            OpCode::SubDocCounter => "SubDoc counter",
199            OpCode::SubDocMultiLookup => "SubDoc multi lookup",
200            OpCode::SubDocMultiMutation => "SubDoc multi mutation",
201            OpCode::SubDocGetCount => "SubDoc get count",
202            OpCode::SubDocReplaceBodyWithXattr => "SubDoc replace body with Xattr",
203            OpCode::Unknown(code) => {
204                return write!(f, "x{code:02x}");
205            }
206        };
207        write!(f, "{txt}")
208    }
209}