diff --git a/src/error.rs b/src/error.rs index 09e2a3d..0d038cf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -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" + ) + }, + } } } @@ -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)] @@ -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`. diff --git a/src/features/serde/mod.rs b/src/features/serde/mod.rs index caed7a6..234b1a2 100644 --- a/src/features/serde/mod.rs +++ b/src/features/serde/mod.rs @@ -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`") + }, + #[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(msg: T) -> Self @@ -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 for EncodeError { fn into(self) -> crate::error::EncodeError {