1use 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}