Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 146 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,119 @@ pub const fn decode_err_from(e: crate::features::serde::DecodeError) -> DecodeEr
}

impl core::fmt::Display for DecodeError {
#[allow(clippy::too_many_lines)]
fn fmt(
&self,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
// TODO: Improve this?
write!(f, "{self:?}")
match self {
| Self::UnexpectedEnd { additional } => {
write!(
f,
"Unexpected end of input. Needed {additional} more bytes"
)
},
| Self::LimitExceeded => write!(f, "The given configuration limit was exceeded"),
| Self::InvalidIntegerType { expected, found } => {
write!(
f,
"Invalid type was found. Expected {expected}, but found {found}"
)
},
| Self::NonZeroTypeIsZero { non_zero_type } => {
write!(
f,
"The decoder tried to decode a NonZero{non_zero_type} but the value was zero"
)
},
| Self::UnexpectedVariant {
type_name,
allowed,
found,
} => {
write!(
f,
"Invalid enum variant was found for {type_name}. Expected {allowed}, but found {found}"
)
},
| Self::Utf8 { inner } => write!(f, "{inner}"),
| Self::InvalidCharEncoding(inner) => {
write!(f, "Failed to decode a char. Bytes: {inner:?}")
},
| Self::InvalidBooleanValue(inner) => {
write!(f, "Failed to decode a bool. Value: {inner}")
},
| Self::InvalidCborInfo(inner) => {
write!(f, "Invalid CBOR additional info value: {inner}")
},
| Self::ArrayLengthMismatch { required, found } => {
write!(
f,
"Array length mismatch. Expected length {required}, but found {found}"
)
},
| Self::OutsideUsizeRange(inner) => {
write!(
f,
"The encoded value {inner} is outside the range of the target usize type"
)
},
| Self::OutsideIsizeRange(inner) => {
write!(
f,
"The encoded value {inner} is outside the range of the target isize type"
)
},
| Self::EmptyEnum { type_name } => {
write!(f, "Tried to decode an enum with no variants: {type_name}")
},
| Self::InvalidDuration { secs, nanos } => {
write!(
f,
"Failed to decode a Duration. Seconds: {secs}, Nanoseconds: {nanos}"
)
},
| Self::InvalidSystemTime { duration } => {
write!(
f,
"Failed to decode a SystemTime. Duration {duration:?} could not be added to UNIX_EPOCH"
)
},
#[cfg(feature = "std")]
| Self::CStringNulError { position } => {
write!(
f,
"Incoming data contained a 0 byte at position {position}"
)
},
#[cfg(feature = "std")]
| Self::Io { inner, additional } => {
write!(f, "IO error: {inner}. Needed {additional} more bytes")
},
| Self::Other(inner) => write!(f, "{inner}"),
#[cfg(feature = "alloc")]
| Self::OtherString(inner) => write!(f, "{inner}"),
#[cfg(feature = "serde")]
| Self::Serde(inner) => write!(f, "{inner}"),
| Self::SchemaMismatch { expected, actual } => {
write!(
f,
"Schema mismatch. Expected hash {expected}, but found {actual}"
)
},
| Self::DuplicateMapKey => {
write!(
f,
"The decoder tried to decode a map, but a duplicate key was found"
)
},
| Self::InvalidMapOrder => {
write!(
f,
"The decoder tried to decode a map, but the keys were not in the correct order"
)
},
}
}
}

Expand Down Expand Up @@ -340,6 +447,20 @@ pub enum AllowedEnumVariants {
Allowed(&'static [u32]),
}

impl core::fmt::Display for AllowedEnumVariants {
fn fmt(
&self,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match self {
| Self::Range { min, max } => write!(f, "min: {min}, max: {max}"),
| Self::Allowed(allowed) => {
write!(f, "allowed: {allowed:?}")
},
}
}
}

/// Integer types. Used by [`DecodeError`\]. These types have no purpose other than being shown in errors.
#[non_exhaustive]
#[derive(Debug, PartialEq, Eq)]
Expand All @@ -362,6 +483,29 @@ pub enum IntegerType {
Reserved,
}

impl core::fmt::Display for IntegerType {
fn fmt(
&self,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match self {
| Self::U8 => write!(f, "u8"),
| Self::U16 => write!(f, "u16"),
| Self::U32 => write!(f, "u32"),
| Self::U64 => write!(f, "u64"),
| Self::U128 => write!(f, "u128"),
| Self::Usize => write!(f, "usize"),
| Self::I8 => write!(f, "i8"),
| Self::I16 => write!(f, "i16"),
| Self::I32 => write!(f, "i32"),
| Self::I64 => write!(f, "i64"),
| Self::I128 => write!(f, "i128"),
| Self::Isize => write!(f, "isize"),
| Self::Reserved => write!(f, "reserved"),
}
}
}

impl IntegerType {
/// Change the `Ux` value to the associated `Ix` value.
/// Returns the old value if `self` is already `Ix`.
Expand Down
69 changes: 69 additions & 0 deletions src/features/serde/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,45 @@ bincode_error_serde! {
}
}

impl core::fmt::Display for DecodeError {
fn fmt(
&self,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match self {
| Self::AnyNotSupported => {
write!(
f,
"Bincode does not support serde's `any` decoding feature."
)
},
| Self::IdentifierNotSupported => {
write!(f, "Bincode does not support serde identifiers")
},
| Self::IgnoredAnyNotSupported => {
write!(f, "Bincode does not support serde's `ignored_any`.")
},
| Self::CannotBorrowOwnedData => {
write!(
f,
"Serde tried decoding a borrowed value from an owned reader. Use `serde_decode_borrowed_from_*` instead"
)
},
#[cfg(not(feature = "alloc"))]
| Self::CannotAllocate => {
write!(f, "Could not allocate data like `String` and `Vec<u8>`")
},
#[cfg(not(feature = "alloc"))]
| Self::CustomError => {
write!(
f,
"Custom serde error but bincode is unable to allocate a string. Set a breakpoint where this is thrown for more information."
)
},
}
}
}

#[cfg(feature = "alloc")]
impl serde::de::Error for crate::error::DecodeError {
fn custom<T>(msg: T) -> Self
Expand Down Expand Up @@ -209,6 +248,36 @@ pub enum EncodeError {
CustomError,
}

impl core::fmt::Display for EncodeError {
fn fmt(
&self,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match self {
| Self::SequenceMustHaveLength => {
write!(
f,
"Serde provided bincode with a sequence without a length, which is not supported in bincode"
)
},
#[cfg(not(feature = "alloc"))]
| Self::CannotCollectStr => {
write!(
f,
"Serializer::collect_str got called but bincode was unable to allocate memory."
)
},
#[cfg(not(feature = "alloc"))]
| Self::CustomError => {
write!(
f,
"Custom serde error but bincode is unable to allocate a string. Set a breakpoint where this is thrown for more information."
)
},
}
}
}

#[allow(clippy::from_over_into)]
impl Into<crate::error::EncodeError> for EncodeError {
fn into(self) -> crate::error::EncodeError {
Expand Down