Skip to main content

couchbase_core/memdx/
status.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, LowerHex};
20
21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
22#[non_exhaustive]
23pub enum Status {
24    // Success indicates the operation completed successfully.
25    Success,
26    // KeyNotFound occurs when an operation is performed on a key that does not exist.
27    KeyNotFound,
28    // KeyExists occurs when an operation is performed on a key that could not be found.
29    KeyExists,
30    // TooBig occurs when an operation attempts to store more data in a single document
31    // than the server is capable of storing (by default, this is a 20MB limit).
32    TooBig,
33    // InvalidArgs occurs when the server receives invalid arguments for an operation.
34    InvalidArgs,
35    // NotStored occurs when the server fails to store a key.
36    NotStored,
37    // BadDelta occurs when performing a counter op and the document is non-numeric.
38    BadDelta,
39    // NotMyVBucket occurs when an operation is dispatched to a server which is
40    // non-authoritative for a specific vbucket.
41    NotMyVbucket,
42    // NoBucket occurs when no bucket was selected on a connection.
43    NoBucket,
44    // Locked occurs when an operation fails due to the document being locked.
45    Locked,
46    // OpaqueNoMatch occurs when the opaque does not match a known stream.
47    OpaqueNoMatch,
48    // WouldThrottle indicates that the operation would have been throttled.
49    WouldThrottle,
50    // ConfigOnly occurs when a data operation is performed on a config-only node.
51    ConfigOnly,
52    // NotLocked occurs when Unlock is performed on an unlocked document.
53    // Added in 7.6.0 under MB-58088.
54    NotLocked,
55    // AuthStale occurs when authentication credentials have become invalidated.
56    AuthStale,
57    // AuthError occurs when the authentication information provided was not valid.
58    AuthError,
59    // AuthContinue occurs in multi-step authentication when more authentication
60    // work needs to be performed in order to complete the authentication process.
61    AuthContinue,
62    // RangeError occurs when the range specified to the server is not valid.
63    RangeError,
64    // AccessError occurs when an access error occurs.
65    AccessError,
66    // NotInitialized is sent by servers which are still initializing, and are not
67    // yet ready to accept operations on behalf of a particular bucket.
68    NotInitialized,
69    // RateLimitedNetworkIngress occurs when the server rate limits due to network ingress.
70    RateLimitedNetworkIngress,
71    // RateLimitedNetworkEgress occurs when the server rate limits due to network egress.
72    RateLimitedNetworkEgress,
73    // RateLimitedMaxConnections occurs when the server rate limits due to the application reaching the maximum
74    // number of allowed connections.
75    RateLimitedMaxConnections,
76    // RateLimitedMaxCommands occurs when the server rate limits due to the application reaching the maximum
77    // number of allowed operations.
78    RateLimitedMaxCommands,
79    // RateLimitedScopeSizeLimitExceeded occurs when the server rate limits due to the application reaching the maximum
80    // data size allowed for the scope.
81    RateLimitedScopeSizeLimitExceeded,
82    // UnknownCommand occurs when an unknown operation is sent to a server.
83    CommandUnknown,
84    // OutOfMemory occurs when the server cannot service a request due to memory
85    // limitations.
86    OutOfMemory,
87    // NotSupported occurs when an operation is understood by the server, but that
88    // operation is not supported on this server (occurs for a variety of reasons).
89    NotSupported,
90    // InternalError occurs when internal errors prevent the server from processing
91    // your request.
92    InternalError,
93    // Busy occurs when the server is too busy to process your request right away.
94    // Attempting the operation at a later time will likely succeed.
95    Busy,
96    // TmpFail occurs when a temporary failure is preventing the server from
97    // processing your request.
98    TmpFail,
99    // CollectionUnknown occurs when a Collection cannot be found.
100    CollectionUnknown,
101    // ScopeUnknown occurs when a Scope cannot be found.
102    ScopeUnknown,
103    // DurabilityInvalidLevel occurs when an invalid durability level was requested.
104    DurabilityInvalidLevel,
105    // DurabilityImpossible occurs when a request is performed with impossible
106    // durability level requirements.
107    DurabilityImpossible,
108    // SyncWriteInProgress occurs when an attempt is made to write to a key that has
109    // a SyncWrite pending.
110    SyncWriteInProgress,
111    // SyncWriteAmbiguous occurs when an SyncWrite does not complete in the specified
112    // time and the result is ambiguous.
113    SyncWriteAmbiguous,
114    // SyncWriteReCommitInProgress occurs when an SyncWrite is being recommitted.
115    SyncWriteRecommitInProgress,
116    // RangeScanCancelled occurs during a range scan to indicate that the range scan was cancelled.
117    RangeScanCancelled,
118    // RangeScanMore occurs during a range scan to indicate that a range scan has more results.
119    RangeScanMore,
120    // RangeScanComplete occurs during a range scan to indicate that a range scan has completed.
121    RangeScanComplete,
122    // RangeScanVbUUIDNotEqual occurs during a range scan to indicate that a vb-uuid mismatch has occurred.
123    RangeScanVBUUIDNotEqual,
124    // SubDocPathNotFound occurs when a sub-document operation targets a path
125    // which does not exist in the specifie document.
126    SubDocPathNotFound,
127    // SubDocPathMismatch occurs when a sub-document operation specifies a path
128    // which does not match the document structure (field access on an array).
129    SubDocPathMismatch,
130    // SubDocPathInvalid occurs when a sub-document path could not be parsed.
131    SubDocPathInvalid,
132    // SubDocPathTooBig occurs when a sub-document path is too big.
133    SubDocPathTooBig,
134    // SubDocDocTooDeep occurs when an operation would cause a document to be
135    // nested beyond the depth limits allowed by the sub-document specification.
136    SubDocDocTooDeep,
137    // SubDocCantInsert occurs when a sub-document operation could not insert.
138    SubDocCantInsert,
139    // SubDocNotJSON occurs when a sub-document operation is performed on a
140    // document which is not JSON.
141    SubDocNotJSON,
142    // SubDocBadRange occurs when a sub-document operation is performed with
143    // a bad range.
144    SubDocBadRange,
145    // SubDocBadDelta occurs when a sub-document counter operation is performed
146    // and the specified delta is not valid.
147    SubDocBadDelta,
148    // SubDocPathExists occurs when a sub-document operation expects a path not
149    // to exists, but the path was found in the document.
150    SubDocPathExists,
151    // SubDocValueTooDeep occurs when a sub-document operation specifies a value
152    // which is deeper than the depth limits of the sub-document specification.
153    SubDocValueTooDeep,
154    // SubDocInvalidCombo occurs when a multi-operation sub-document operation is
155    // performed and operations within the package of ops conflict with each other.
156    SubDocInvalidCombo,
157    // SubDocMultiPathFailure occurs when a multi-operation sub-document operation is
158    // performed and operations within the package of ops conflict with each other.
159    SubDocMultiPathFailure,
160    // SubDocSuccessDeleted occurs when a multi-operation sub-document operation
161    // is performed on a soft-deleted document.
162    SubDocSuccessDeleted,
163    // SubDocXattrInvalidFlagCombo occurs when an invalid set of
164    // extended-attribute flags is passed to a sub-document operation.
165    SubDocXattrInvalidFlagCombo,
166    // SubDocXattrInvalidKeyCombo occurs when an invalid set of key operations
167    // are specified for a extended-attribute sub-document operation.
168    SubDocXattrInvalidKeyCombo,
169    // SubDocXattrUnknownMacro occurs when an invalid macro value is specified.
170    SubDocXattrUnknownMacro,
171    // SubDocXattrUnknownVAttr occurs when an invalid virtual attribute is specified.
172    SubDocXattrUnknownVAttr,
173    // SubDocXattrCannotModifyVAttr occurs when a mutation is attempted upon
174    // a virtual attribute (which are immutable by definition).
175    SubDocXattrCannotModifyVAttr,
176    // SubDocMultiPathFailureDeleted occurs when a Multi Path Failure occurs on
177    // a soft-deleted document.
178    SubDocMultiPathFailureDeleted,
179    // SubDocInvalidXattrOrder occurs when xattr operations exist after non-xattr
180    // operations in the operation list.
181    SubDocInvalidXattrOrder,
182    // SubDocXattrUnknownVattrMacro occurs when you try to use an unknown vattr.
183    SubDocXattrUnknownVattrMacro,
184    // SubDocCanOnlyReviveDeletedDocuments occurs when you try to revive a document
185    // which is not currently in the soft-deleted state.
186    SubDocCanOnlyReviveDeletedDocuments,
187    // SubDocDeletedDocumentCantHaveValue occurs when you try set a value to a
188    // soft-deleted document.
189    SubDocDeletedDocumentCantHaveValue,
190
191    Unknown(u16),
192}
193
194impl From<Status> for u16 {
195    fn from(value: Status) -> Self {
196        Self::from(&value)
197    }
198}
199
200impl From<&Status> for u16 {
201    fn from(value: &Status) -> Self {
202        match value {
203            Status::Success => 0x00,
204            Status::KeyNotFound => 0x01,
205            Status::KeyExists => 0x02,
206            Status::TooBig => 0x03,
207            Status::InvalidArgs => 0x04,
208            Status::NotStored => 0x05,
209            Status::BadDelta => 0x06,
210            Status::NotMyVbucket => 0x07,
211            Status::NoBucket => 0x08,
212            Status::Locked => 0x09,
213            Status::OpaqueNoMatch => 0x0b,
214            Status::WouldThrottle => 0x0c,
215            Status::ConfigOnly => 0x0d,
216            Status::NotLocked => 0x0e,
217            Status::AuthStale => 0x1f,
218            Status::AuthError => 0x20,
219            Status::AuthContinue => 0x21,
220            Status::RangeError => 0x22,
221            Status::AccessError => 0x24,
222            Status::NotInitialized => 0x25,
223            Status::RateLimitedNetworkIngress => 0x30,
224            Status::RateLimitedNetworkEgress => 0x31,
225            Status::RateLimitedMaxConnections => 0x32,
226            Status::RateLimitedMaxCommands => 0x33,
227            Status::RateLimitedScopeSizeLimitExceeded => 0x34,
228            Status::CommandUnknown => 0x81,
229            Status::OutOfMemory => 0x82,
230            Status::NotSupported => 0x83,
231            Status::InternalError => 0x84,
232            Status::Busy => 0x85,
233            Status::TmpFail => 0x86,
234            Status::CollectionUnknown => 0x88,
235            Status::ScopeUnknown => 0x8c,
236            Status::DurabilityInvalidLevel => 0xa0,
237            Status::DurabilityImpossible => 0xa1,
238            Status::SyncWriteInProgress => 0xa2,
239            Status::SyncWriteAmbiguous => 0xa3,
240            Status::SyncWriteRecommitInProgress => 0xa4,
241            Status::RangeScanCancelled => 0xa5,
242            Status::RangeScanMore => 0xa6,
243            Status::RangeScanComplete => 0xa7,
244            Status::RangeScanVBUUIDNotEqual => 0xa8,
245            Status::SubDocPathNotFound => 0xc0,
246            Status::SubDocPathMismatch => 0xc1,
247            Status::SubDocPathInvalid => 0xc2,
248            Status::SubDocPathTooBig => 0xc3,
249            Status::SubDocDocTooDeep => 0xc4,
250            Status::SubDocCantInsert => 0xc5,
251            Status::SubDocNotJSON => 0xc6,
252            Status::SubDocBadRange => 0xc7,
253            Status::SubDocBadDelta => 0xc8,
254            Status::SubDocPathExists => 0xc9,
255            Status::SubDocValueTooDeep => 0xca,
256            Status::SubDocInvalidCombo => 0xcb,
257            Status::SubDocMultiPathFailure => 0xcc,
258            Status::SubDocSuccessDeleted => 0xcd,
259            Status::SubDocXattrInvalidFlagCombo => 0xce,
260            Status::SubDocXattrInvalidKeyCombo => 0xcf,
261            Status::SubDocXattrUnknownMacro => 0xd0,
262            Status::SubDocXattrUnknownVAttr => 0xd1,
263            Status::SubDocXattrCannotModifyVAttr => 0xd2,
264            Status::SubDocMultiPathFailureDeleted => 0xd3,
265            Status::SubDocInvalidXattrOrder => 0xd4,
266            Status::SubDocXattrUnknownVattrMacro => 0xd5,
267            Status::SubDocCanOnlyReviveDeletedDocuments => 0xd6,
268            Status::SubDocDeletedDocumentCantHaveValue => 0xd7,
269
270            Status::Unknown(value) => *value,
271        }
272    }
273}
274
275impl From<u16> for Status {
276    fn from(value: u16) -> Self {
277        match value {
278            0x00 => Status::Success,
279            0x01 => Status::KeyNotFound,
280            0x02 => Status::KeyExists,
281            0x03 => Status::TooBig,
282            0x04 => Status::InvalidArgs,
283            0x05 => Status::NotStored,
284            0x06 => Status::BadDelta,
285            0x07 => Status::NotMyVbucket,
286            0x08 => Status::NoBucket,
287            0x09 => Status::Locked,
288            0x0b => Status::OpaqueNoMatch,
289            0x0c => Status::WouldThrottle,
290            0x0d => Status::ConfigOnly,
291            0x0e => Status::NotLocked,
292            0x1f => Status::AuthStale,
293            0x20 => Status::AuthError,
294            0x21 => Status::AuthContinue,
295            0x22 => Status::RangeError,
296            0x24 => Status::AccessError,
297            0x25 => Status::NotInitialized,
298            0x30 => Status::RateLimitedNetworkIngress,
299            0x31 => Status::RateLimitedNetworkEgress,
300            0x32 => Status::RateLimitedMaxConnections,
301            0x33 => Status::RateLimitedMaxCommands,
302            0x34 => Status::RateLimitedScopeSizeLimitExceeded,
303            0x81 => Status::CommandUnknown,
304            0x82 => Status::OutOfMemory,
305            0x83 => Status::NotSupported,
306            0x84 => Status::InternalError,
307            0x85 => Status::Busy,
308            0x86 => Status::TmpFail,
309            0x88 => Status::CollectionUnknown,
310            0x8c => Status::ScopeUnknown,
311            0xa0 => Status::DurabilityInvalidLevel,
312            0xa1 => Status::DurabilityImpossible,
313            0xa2 => Status::SyncWriteInProgress,
314            0xa3 => Status::SyncWriteAmbiguous,
315            0xa4 => Status::SyncWriteRecommitInProgress,
316            0xa5 => Status::RangeScanCancelled,
317            0xa6 => Status::RangeScanMore,
318            0xa7 => Status::RangeScanComplete,
319            0xa8 => Status::RangeScanVBUUIDNotEqual,
320            0xc0 => Status::SubDocPathNotFound,
321            0xc1 => Status::SubDocPathMismatch,
322            0xc2 => Status::SubDocPathInvalid,
323            0xc3 => Status::SubDocPathTooBig,
324            0xc4 => Status::SubDocDocTooDeep,
325            0xc5 => Status::SubDocCantInsert,
326            0xc6 => Status::SubDocNotJSON,
327            0xc7 => Status::SubDocBadRange,
328            0xc8 => Status::SubDocBadDelta,
329            0xc9 => Status::SubDocPathExists,
330            0xca => Status::SubDocValueTooDeep,
331            0xcb => Status::SubDocInvalidCombo,
332            0xcc => Status::SubDocMultiPathFailure,
333            0xcd => Status::SubDocSuccessDeleted,
334            0xce => Status::SubDocXattrInvalidFlagCombo,
335            0xcf => Status::SubDocXattrInvalidKeyCombo,
336            0xd0 => Status::SubDocXattrUnknownMacro,
337            0xd1 => Status::SubDocXattrUnknownVAttr,
338            0xd2 => Status::SubDocXattrCannotModifyVAttr,
339            0xd3 => Status::SubDocMultiPathFailureDeleted,
340            0xd4 => Status::SubDocInvalidXattrOrder,
341            0xd5 => Status::SubDocXattrUnknownVattrMacro,
342            0xd6 => Status::SubDocCanOnlyReviveDeletedDocuments,
343            0xd7 => Status::SubDocDeletedDocumentCantHaveValue,
344
345            _ => Status::Unknown(value),
346        }
347    }
348}
349
350impl Display for Status {
351    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
352        let txt = match self {
353            Status::AuthError => "authentication error",
354            Status::NotMyVbucket => "not my vbucket",
355            Status::Success => "success",
356            Status::TmpFail => "temporary failure",
357            Status::AuthContinue => "authentication continue",
358            Status::KeyExists => "key exists",
359            Status::NotStored => "not stored",
360            Status::TooBig => "too big",
361            Status::Locked => "locked",
362            Status::NotLocked => "not locked",
363            Status::ScopeUnknown => "scope unknown",
364            Status::CollectionUnknown => "collection unknown",
365            Status::AccessError => "access error",
366            Status::KeyNotFound => "key not found",
367            Status::InvalidArgs => "invalid args",
368            Status::NoBucket => "no bucket selected",
369            Status::SubDocPathNotFound => "subdoc path not found",
370            Status::SubDocPathMismatch => "subdoc path mismatch",
371            Status::SubDocPathInvalid => "subdoc path invalid",
372            Status::SubDocPathTooBig => "subdoc path too big",
373            Status::SubDocDocTooDeep => "subdoc document too deep",
374            Status::SubDocCantInsert => "subdoc can't insert",
375            Status::SubDocNotJSON => "subdoc not JSON",
376            Status::SubDocBadRange => "subdoc bad range",
377            Status::SubDocBadDelta => "subdoc bad delta",
378            Status::SubDocPathExists => "subdoc path exists",
379            Status::SubDocValueTooDeep => "subdoc value too deep",
380            Status::SubDocInvalidCombo => "subdoc invalid combo",
381            Status::SubDocMultiPathFailure => "subdoc multipath failure",
382            Status::SubDocSuccessDeleted => "subdoc success deleted",
383            Status::SubDocXattrInvalidFlagCombo => "subdoc xattr invalid flag combo",
384            Status::SubDocXattrInvalidKeyCombo => "subdoc xattr invalid key combo",
385            Status::SubDocXattrUnknownMacro => "subdoc xattr unknown macro",
386            Status::SubDocXattrUnknownVAttr => "subdoc xattr unknown vattr",
387            Status::SubDocXattrCannotModifyVAttr => "subdoc xattr cannot modify vattr",
388            Status::SubDocMultiPathFailureDeleted => "subdoc multipath failure deleted",
389            Status::SubDocInvalidXattrOrder => "subdoc invalid xattr order",
390            Status::SubDocXattrUnknownVattrMacro => "subdoc xattr unknown vattr macro",
391            Status::SubDocCanOnlyReviveDeletedDocuments => {
392                "subdoc can only revive deleted documents"
393            }
394            Status::SubDocDeletedDocumentCantHaveValue => {
395                "subdoc deleted document can't have value"
396            }
397            Status::BadDelta => "bad delta",
398            Status::OpaqueNoMatch => "opaque no match",
399            Status::WouldThrottle => "would throttle",
400            Status::ConfigOnly => "config only",
401            Status::AuthStale => "authentication stale",
402            Status::RangeError => "range error",
403            Status::NotInitialized => "not initialized",
404            Status::RateLimitedNetworkIngress => "rate limited: network ingress",
405            Status::RateLimitedNetworkEgress => "rate limited: network egress",
406            Status::RateLimitedMaxConnections => "rate limited: max connections",
407            Status::RateLimitedMaxCommands => "rate limited: max commands",
408            Status::RateLimitedScopeSizeLimitExceeded => "rate limited: scope size limit exceeded",
409            Status::CommandUnknown => "unknown command",
410            Status::OutOfMemory => "out of memory",
411            Status::NotSupported => "not supported",
412            Status::InternalError => "internal error",
413            Status::Busy => "busy",
414            Status::DurabilityInvalidLevel => "durability invalid level",
415            Status::DurabilityImpossible => "durability impossible",
416            Status::SyncWriteInProgress => "sync write in progress",
417            Status::SyncWriteAmbiguous => "sync write ambiguous",
418            Status::SyncWriteRecommitInProgress => "sync write recommit in progress",
419            Status::RangeScanCancelled => "range scan cancelled",
420            Status::RangeScanMore => "range scan more",
421            Status::RangeScanComplete => "range scan complete",
422            Status::RangeScanVBUUIDNotEqual => "range scan vb-uuid not equal",
423            Status::Unknown(status) => {
424                let t = format!("unknown status 0x{status:x}");
425
426                write!(f, "{t}")?;
427                return Ok(());
428            }
429        };
430
431        write!(f, "{txt}")
432    }
433}