1use core::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum ErrorCode {
9 InvalidLimits,
11
12 UnexpectedEof,
14 LengthOverflow,
16 TrailingBytes,
18 AllocationFailed,
20 ArrayLenMismatch,
22 MapLenMismatch,
24
25 DepthLimitExceeded,
27 TotalItemsLimitExceeded,
29 ArrayLenLimitExceeded,
31 MapLenLimitExceeded,
33 BytesLenLimitExceeded,
35 TextLenLimitExceeded,
37 MessageLenLimitExceeded,
39
40 ReservedAdditionalInfo,
42 IndefiniteLengthForbidden,
44 NonCanonicalEncoding,
46
47 MapKeyMustBeText,
49 DuplicateMapKey,
51 NonCanonicalMapOrder,
53 NonCanonicalSetOrder,
55
56 ForbiddenOrMalformedTag,
58 BignumNotCanonical,
60 BignumMustBeOutsideSafeRange,
62
63 UnsupportedSimpleValue,
65 IntegerOutsideSafeRange,
67
68 Utf8Invalid,
70
71 NegativeZeroForbidden,
73 NonCanonicalNaN,
75
76 SerdeError,
78
79 ExpectedMap,
81 ExpectedArray,
83 ExpectedInteger,
85 ExpectedText,
87 ExpectedBytes,
89 ExpectedBool,
91 ExpectedNull,
93 ExpectedFloat,
95 ExpectedEnum,
97 UnknownEnumVariant,
99
100 PatchConflict,
102 IndexOutOfBounds,
104
105 InvalidQuery,
107 MissingKey,
109 MalformedCanonical,
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
117pub struct CborError {
118 pub code: ErrorCode,
120 pub offset: usize,
122}
123
124impl CborError {
125 #[inline]
127 #[must_use]
128 pub const fn new(code: ErrorCode, offset: usize) -> Self {
129 Self { code, offset }
130 }
131}
132
133impl fmt::Display for CborError {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 let msg = match self.code {
136 ErrorCode::InvalidLimits => "invalid CBOR limits",
137
138 ErrorCode::UnexpectedEof => "unexpected end of input",
139 ErrorCode::LengthOverflow => "length overflow",
140 ErrorCode::TrailingBytes => "trailing bytes after single CBOR item",
141 ErrorCode::AllocationFailed => "allocation failed",
142 ErrorCode::ArrayLenMismatch => "array length mismatch",
143 ErrorCode::MapLenMismatch => "map length mismatch",
144
145 ErrorCode::DepthLimitExceeded => "nesting depth limit exceeded",
146 ErrorCode::TotalItemsLimitExceeded => "total items limit exceeded",
147 ErrorCode::ArrayLenLimitExceeded => "array length exceeds decode limits",
148 ErrorCode::MapLenLimitExceeded => "map length exceeds decode limits",
149 ErrorCode::BytesLenLimitExceeded => "byte string length exceeds decode limits",
150 ErrorCode::TextLenLimitExceeded => "text string length exceeds decode limits",
151 ErrorCode::MessageLenLimitExceeded => "input length exceeds decode limits",
152
153 ErrorCode::ReservedAdditionalInfo => "reserved additional info value",
154 ErrorCode::IndefiniteLengthForbidden => "indefinite length forbidden",
155 ErrorCode::NonCanonicalEncoding => "non-canonical integer/length encoding",
156
157 ErrorCode::MapKeyMustBeText => "map keys must be text strings",
158 ErrorCode::DuplicateMapKey => "duplicate map key",
159 ErrorCode::NonCanonicalMapOrder => "non-canonical map key order",
160 ErrorCode::NonCanonicalSetOrder => "non-canonical set element order",
161
162 ErrorCode::ForbiddenOrMalformedTag => "forbidden or malformed CBOR tag",
163 ErrorCode::BignumNotCanonical => {
164 "bignum magnitude must be canonical (non-empty, no leading zero)"
165 }
166 ErrorCode::BignumMustBeOutsideSafeRange => "bignum must be outside int_safe range",
167
168 ErrorCode::UnsupportedSimpleValue => "unsupported CBOR simple value",
169 ErrorCode::IntegerOutsideSafeRange => "integer outside int_safe range",
170
171 ErrorCode::Utf8Invalid => "text must be valid UTF-8",
172
173 ErrorCode::NegativeZeroForbidden => "negative zero forbidden",
174 ErrorCode::NonCanonicalNaN => "non-canonical NaN encoding",
175 ErrorCode::SerdeError => "serde conversion failed",
176
177 ErrorCode::ExpectedMap => "expected CBOR map",
178 ErrorCode::ExpectedArray => "expected CBOR array",
179 ErrorCode::ExpectedInteger => "expected CBOR integer",
180 ErrorCode::ExpectedText => "expected CBOR text string",
181 ErrorCode::ExpectedBytes => "expected CBOR byte string",
182 ErrorCode::ExpectedBool => "expected CBOR bool",
183 ErrorCode::ExpectedNull => "expected CBOR null",
184 ErrorCode::ExpectedFloat => "expected CBOR float64",
185 ErrorCode::ExpectedEnum => "expected CBOR enum value",
186 ErrorCode::UnknownEnumVariant => "unknown CBOR enum variant",
187 ErrorCode::PatchConflict => "patch operations conflict",
188 ErrorCode::IndexOutOfBounds => "array index out of bounds",
189 ErrorCode::InvalidQuery => "invalid query arguments",
190 ErrorCode::MissingKey => "missing required map key",
191 ErrorCode::MalformedCanonical => "malformed canonical CBOR",
192 };
193
194 write!(f, "cbor error at {}: {msg}", self.offset)
195 }
196}
197
198#[cfg(feature = "std")]
199impl std::error::Error for CborError {}