Coverage Report

Created: 2026-07-13 08:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bincode-2.0.1/src/error.rs
Line
Count
Source
1
//! Errors that can be encounting by Encoding and Decoding.
2
3
/// Errors that can be encountered by encoding a type
4
#[non_exhaustive]
5
#[derive(Debug)]
6
pub enum EncodeError {
7
    /// The writer ran out of storage.
8
    UnexpectedEnd,
9
10
    /// The `RefCell<T>` is already borrowed
11
    RefCellAlreadyBorrowed {
12
        /// The inner borrow error
13
        inner: core::cell::BorrowError,
14
        /// the type name of the RefCell being encoded that is currently borrowed.
15
        type_name: &'static str,
16
    },
17
18
    /// An uncommon error occurred, see the inner text for more information
19
    Other(&'static str),
20
21
    /// An uncommon error occurred, see the inner text for more information
22
    #[cfg(feature = "alloc")]
23
    OtherString(alloc::string::String),
24
25
    /// A `std::path::Path` was being encoded but did not contain a valid `&str` representation
26
    #[cfg(feature = "std")]
27
    InvalidPathCharacters,
28
29
    /// The targeted writer encountered an `std::io::Error`
30
    #[cfg(feature = "std")]
31
    Io {
32
        /// The encountered error
33
        inner: std::io::Error,
34
        /// The amount of bytes that were written before the error occurred
35
        index: usize,
36
    },
37
38
    /// The encoder tried to encode a `Mutex` or `RwLock`, but the locking failed
39
    #[cfg(feature = "std")]
40
    LockFailed {
41
        /// The type name of the mutex for debugging purposes
42
        type_name: &'static str,
43
    },
44
45
    /// The encoder tried to encode a `SystemTime`, but it was before `SystemTime::UNIX_EPOCH`
46
    #[cfg(feature = "std")]
47
    InvalidSystemTime {
48
        /// The error that was thrown by the SystemTime
49
        inner: std::time::SystemTimeError,
50
        /// The SystemTime that caused the error
51
        time: std::boxed::Box<std::time::SystemTime>,
52
    },
53
54
    #[cfg(feature = "serde")]
55
    /// A serde-specific error that occurred while decoding.
56
    Serde(crate::features::serde::EncodeError),
57
}
58
59
impl core::fmt::Display for EncodeError {
60
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
61
        // TODO: Improve this?
62
0
        write!(f, "{:?}", self)
63
0
    }
64
}
65
66
/// Errors that can be encountered by decoding a type
67
#[non_exhaustive]
68
#[derive(Debug)]
69
pub enum DecodeError {
70
    /// The reader reached its end but more bytes were expected.
71
    UnexpectedEnd {
72
        /// Gives an estimate of how many extra bytes are needed.
73
        ///
74
        /// **Note**: this is only an estimate and not indicative of the actual bytes needed.
75
        ///
76
        /// **Note**: Bincode has no look-ahead mechanism. This means that this will only return the amount of bytes to be read for the current action, and not take into account the entire data structure being read.
77
        additional: usize,
78
    },
79
80
    /// The given configuration limit was exceeded
81
    LimitExceeded,
82
83
    /// Invalid type was found. The decoder tried to read type `expected`, but found type `found` instead.
84
    InvalidIntegerType {
85
        /// The type that was being read from the reader
86
        expected: IntegerType,
87
        /// The type that was encoded in the data
88
        found: IntegerType,
89
    },
90
91
    /// The decoder tried to decode any of the `NonZero*` types but the value is zero
92
    NonZeroTypeIsZero {
93
        /// The type that was being read from the reader
94
        non_zero_type: IntegerType,
95
    },
96
97
    /// Invalid enum variant was found. The decoder tried to decode variant index `found`, but the variant index should be between `min` and `max`.
98
    UnexpectedVariant {
99
        /// The type name that was being decoded.
100
        type_name: &'static str,
101
102
        /// The variants that are allowed
103
        allowed: &'static AllowedEnumVariants,
104
105
        /// The index of the enum that the decoder encountered
106
        found: u32,
107
    },
108
109
    /// The decoder tried to decode a `str`, but an utf8 error was encountered.
110
    Utf8 {
111
        /// The inner error
112
        inner: core::str::Utf8Error,
113
    },
114
115
    /// The decoder tried to decode a `char` and failed. The given buffer contains the bytes that are read at the moment of failure.
116
    InvalidCharEncoding([u8; 4]),
117
118
    /// The decoder tried to decode a `bool` and failed. The given value is what is actually read.
119
    InvalidBooleanValue(u8),
120
121
    /// The decoder tried to decode an array of length `required`, but the binary data contained an array of length `found`.
122
    ArrayLengthMismatch {
123
        /// The length of the array required by the rust type.
124
        required: usize,
125
        /// The length of the array found in the binary format.
126
        found: usize,
127
    },
128
129
    /// The encoded value is outside of the range of the target usize type.
130
    ///
131
    /// This can happen if an usize was encoded on an architecture with a larger
132
    /// usize type and then decoded on an architecture with a smaller one. For
133
    /// example going from a 64 bit architecture to a 32 or 16 bit one may
134
    /// cause this error.
135
    OutsideUsizeRange(u64),
136
137
    /// Tried to decode an enum with no variants
138
    EmptyEnum {
139
        /// The type that was being decoded
140
        type_name: &'static str,
141
    },
142
143
    /// The decoder tried to decode a Duration and overflowed the number of seconds.
144
    InvalidDuration {
145
        /// The number of seconds in the duration.
146
        secs: u64,
147
148
        /// The number of nanoseconds in the duration, which when converted to seconds and added to
149
        /// `secs`, overflows a `u64`.
150
        nanos: u32,
151
    },
152
153
    /// The decoder tried to decode a SystemTime and overflowed
154
    InvalidSystemTime {
155
        /// The duration which could not have been added to
156
        /// [`UNIX_EPOCH`](std::time::SystemTime::UNIX_EPOCH)
157
        duration: core::time::Duration,
158
    },
159
160
    /// The decoder tried to decode a `CString`, but the incoming data contained a 0 byte
161
    #[cfg(feature = "std")]
162
    CStringNulError {
163
        /// Nul byte position
164
        position: usize,
165
    },
166
167
    /// The reader encountered an IO error but more bytes were expected.
168
    #[cfg(feature = "std")]
169
    Io {
170
        /// The IO error expected
171
        inner: std::io::Error,
172
173
        /// Gives an estimate of how many extra bytes are needed.
174
        ///
175
        /// **Note**: this is only an estimate and not indicative of the actual bytes needed.
176
        ///
177
        /// **Note**: Bincode has no look-ahead mechanism. This means that this will only return the amount of bytes to be read for the current action, and not take into account the entire data structure being read.
178
        additional: usize,
179
    },
180
181
    /// An uncommon error occurred, see the inner text for more information
182
    Other(&'static str),
183
184
    /// An uncommon error occurred, see the inner text for more information
185
    #[cfg(feature = "alloc")]
186
    OtherString(alloc::string::String),
187
188
    #[cfg(feature = "serde")]
189
    /// A serde-specific error that occurred while decoding.
190
    Serde(crate::features::serde::DecodeError),
191
}
192
193
impl core::fmt::Display for DecodeError {
194
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
195
        // TODO: Improve this?
196
0
        write!(f, "{:?}", self)
197
0
    }
198
}
199
200
impl DecodeError {
201
    /// If the current error is `InvalidIntegerType`, change the `expected` and
202
    /// `found` values from `Ux` to `Ix`. This is needed to have correct error
203
    /// reporting in src/varint/decode_signed.rs since this calls
204
    /// src/varint/decode_unsigned.rs and needs to correct the `expected` and
205
    /// `found` types.
206
0
    pub(crate) fn change_integer_type_to_signed(self) -> DecodeError {
207
0
        match self {
208
0
            Self::InvalidIntegerType { expected, found } => Self::InvalidIntegerType {
209
0
                expected: expected.into_signed(),
210
0
                found: found.into_signed(),
211
0
            },
212
0
            other => other,
213
        }
214
0
    }
215
}
216
217
/// Indicates which enum variants are allowed
218
#[non_exhaustive]
219
#[derive(Debug, PartialEq, Eq)]
220
pub enum AllowedEnumVariants {
221
    /// All values between `min` and `max` (inclusive) are allowed
222
    #[allow(missing_docs)]
223
    Range { min: u32, max: u32 },
224
    /// Each one of these values is allowed
225
    Allowed(&'static [u32]),
226
}
227
228
/// Integer types. Used by [DecodeError]. These types have no purpose other than being shown in errors.
229
#[non_exhaustive]
230
#[derive(Debug, PartialEq, Eq)]
231
#[allow(missing_docs)]
232
pub enum IntegerType {
233
    U8,
234
    U16,
235
    U32,
236
    U64,
237
    U128,
238
    Usize,
239
240
    I8,
241
    I16,
242
    I32,
243
    I64,
244
    I128,
245
    Isize,
246
247
    Reserved,
248
}
249
250
impl IntegerType {
251
    /// Change the `Ux` value to the associated `Ix` value.
252
    /// Returns the old value if `self` is already `Ix`.
253
0
    pub(crate) const fn into_signed(self) -> Self {
254
0
        match self {
255
0
            Self::U8 => Self::I8,
256
0
            Self::U16 => Self::I16,
257
0
            Self::U32 => Self::I32,
258
0
            Self::U64 => Self::I64,
259
0
            Self::U128 => Self::I128,
260
0
            Self::Usize => Self::Isize,
261
262
0
            other => other,
263
        }
264
0
    }
265
}