1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
use core::fmt::Display;
/// Represents an error that can occur during CBOR encoding or decoding.
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
/// The initial byte is not a valid head, or names a major type this
/// reader cannot handle.
InvalidInitialByte(u8),
/// A text string contained a character that is not valid UTF-8.
InvalidChar,
/// A text string's bytes are not valid UTF-8.
InvalidUtf8(core::str::Utf8Error),
/// A fixed-size output buffer ran out of room before the value was complete.
BufferTooSmall,
/// A borrow was requested from a reader that cannot lend out its buffer.
CannotBorrow,
/// An array's encoded length did not match the number of fields the target
/// type has.
ArrayLengthMismatch {
/// The number of elements the target type requires.
expected: usize,
/// The number of elements the input declared.
actual: usize,
},
/// A map's encoded length did not match the number of entries the type requires.
MapLengthMismatch {
/// The number of entries the target type requires.
expected: usize,
/// The number of entries the input declared.
actual: usize,
},
/// A break stop code (`0xff`) appeared where no indefinite-length item was
/// open.
UnexpectedBreak,
/// A value was untagged, or tagged with a different number, than the one
/// its type declares. A value read from the wrong tag is a different value.
TagMismatch {
/// The tag the type declared.
expected: u64,
/// The tag that was on the wire, or `None` if the value was untagged.
found: Option<u64>,
},
/// A value arrived under a tag its type does not declare. The mirror of
/// [`Error::TagMismatch`].
UnexpectedTag {
/// The tag that was on the wire.
found: u64,
},
/// A map held the same key twice.
///
/// RFC 8949 Section 5.6 leaves this undefined and permits rejection.
/// Keeping the last would make the result depend on the decoder.
DuplicateKey,
/// A floating-point value was decoded but does not fit the requested Rust
/// type exactly.
FloatNotExactlyRepresentable,
/// An indefinite-length container was not closed by a break stop code.
UnexpectedEndOfContainer {
/// The byte that was found where the break should have been.
byte: u8,
},
/// A head's additional information is not one RFC 8949 defines: `28`
/// through `30` are unassigned, and `31` is a length, not a scalar.
InvalidAdditionalInfo(u8),
/// A float payload was truncated, or its marker was not a CBOR float width.
InvalidFloatEncoding,
/// A simple value below 32 arrived in the two-byte form, which RFC 8949
/// Section 3.3 gives no meaning to.
InvalidSimpleValue(u8),
/// A CBOR integer was decoded but does not fit the requested Rust type.
IntegerOutOfRange,
/// The depth limit was exceeded while decoding a nested structure.
DepthLimitExceeded,
/// A map did not contain a key that the target type requires.
KeyNotFound(alloc::string::String),
/// A map contained the same key twice.
KeyDuplicated(alloc::string::String),
/// A map-mode enum found a variant name it does not know.
UnknownVariant(alloc::string::String),
/// An array-mode enum found a variant index it does not know.
UnknownVariantIndex(u32),
/// A `c_enum` integer did not match any Rust discriminant.
UnknownVariantDiscriminant(i128),
/// An underlying [`std::io`] operation failed.
#[cfg(feature = "std")]
IoError(std::io::Error),
}
/// The result of a CBOR encoding or decoding operation.
pub type Result<T> = core::result::Result<T, Error>;
impl Error {
#[doc(hidden)]
#[inline]
pub fn key_not_found(key: &str) -> Self {
Error::KeyNotFound(alloc::string::String::from(key))
}
#[doc(hidden)]
#[inline]
pub fn key_duplicated(key: &str) -> Self {
Error::KeyDuplicated(alloc::string::String::from(key))
}
#[doc(hidden)]
#[inline]
pub fn unknown_variant(name: &str) -> Self {
Error::UnknownVariant(alloc::string::String::from(name))
}
}
impl Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Error::InvalidInitialByte(byte) => write!(f, "Invalid initial byte: 0x{:02x}", byte),
Error::InvalidChar => write!(f, "Invalid character"),
Error::InvalidUtf8(err) => write!(f, "Invalid UTF-8: {}", err),
Error::BufferTooSmall => write!(f, "Buffer too small"),
Error::CannotBorrow => write!(f, "Cannot borrow data from original buffer"),
Error::ArrayLengthMismatch { expected, actual } => {
write!(
f,
"Array length mismatch: expected {}, actual {}",
expected, actual
)
}
Error::MapLengthMismatch { expected, actual } => {
write!(
f,
"Map length mismatch: expected {}, actual {}",
expected, actual
)
}
Error::UnexpectedBreak => write!(f, "Unexpected break code"),
Error::TagMismatch { expected, found } => match found {
Some(found) => write!(f, "Expected tag {expected} but the value is tagged {found}"),
None => write!(f, "Expected tag {expected} but the value is not tagged"),
},
Error::UnexpectedTag { found } => {
write!(f, "Value is tagged {found} but its type declares no tag")
}
Error::DuplicateKey => write!(f, "Map has a duplicate key"),
Error::FloatNotExactlyRepresentable => {
write!(f, "Float is not exactly representable in the target type")
}
Error::UnexpectedEndOfContainer { byte } => write!(
f,
"Indefinite-length container was not closed by a break code, found 0x{:02x}",
byte
),
Error::InvalidAdditionalInfo(info) => {
write!(f, "Invalid additional information: {}", info)
}
Error::InvalidFloatEncoding => write!(f, "Invalid floating-point encoding"),
Error::InvalidSimpleValue(value) => write!(f, "Invalid simple value: {}", value),
Error::IntegerOutOfRange => write!(f, "Integer out of range for the target type"),
Error::DepthLimitExceeded => {
write!(f, "Maximum deserialization depth exceeded")
}
Error::KeyNotFound(key) => write!(f, "Key '{}' not found", key),
Error::KeyDuplicated(key) => write!(f, "Key '{}' is duplicated", key),
Error::UnknownVariant(name) => write!(f, "Unknown variant '{}'", name),
Error::UnknownVariantIndex(index) => write!(f, "Unknown variant index {}", index),
Error::UnknownVariantDiscriminant(value) => {
write!(f, "Unknown variant discriminant {}", value)
}
#[cfg(feature = "std")]
Error::IoError(err) => err.fmt(f),
}
}
}
impl core::error::Error for Error {}