use super::*;
use core::str::Utf8Error;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum VerboseDecodeError {
InvalidTypeInfo([u8; 4]),
InvalidBoolValue(u8),
UnexpectedEndOfSlice(UnexpectedEndOfSliceError),
VariableNameStringMissingNullTermination,
VariableUnitStringMissingNullTermination,
ArrayDimensionsOverflow,
StructDataLengthOverflow,
Utf8(Utf8Error),
}
impl core::fmt::Display for VerboseDecodeError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use VerboseDecodeError::*;
match self {
InvalidTypeInfo(value) => write!(
f, "DLT Verbose Message Field: Encountered an invalid typeinfo {:?} (contradicting or unknown)", value
),
InvalidBoolValue(value) => write!(
f, "DLT Verbose Message Field: Encountered invalid bool value '{}' (only 0 or 1 are valid)", value
),
UnexpectedEndOfSlice(err) => err.fmt(f),
VariableNameStringMissingNullTermination => write!(
f, "DLT Verbose Message Field: Encountered a variable name string missing the terminating zero value"
),
VariableUnitStringMissingNullTermination => write!(
f, "DLT Verbose Message Field: Encountered a variable unit string missing the terminating zero value"
),
Utf8(err) => err.fmt(f),
ArrayDimensionsOverflow => write!(f, "DLT Verbose Message Field: Array dimension sizes too big. Calculating the overall array size would cause an integer overflow."),
StructDataLengthOverflow => write!(f, "DLT Verbose Message Field: Struct data length too big. Would cause an integer overflow."),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for VerboseDecodeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use VerboseDecodeError::*;
match self {
InvalidTypeInfo(_) => None,
InvalidBoolValue(_) => None,
UnexpectedEndOfSlice(err) => Some(err),
VariableNameStringMissingNullTermination => None,
VariableUnitStringMissingNullTermination => None,
Utf8(err) => Some(err),
ArrayDimensionsOverflow => None,
StructDataLengthOverflow => None,
}
}
}
impl From<Utf8Error> for VerboseDecodeError {
fn from(err: Utf8Error) -> VerboseDecodeError {
VerboseDecodeError::Utf8(err)
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::format;
#[test]
fn clone_eq() {
use VerboseDecodeError::*;
let v = InvalidBoolValue(2);
assert_eq!(v, v.clone());
}
#[test]
fn debug() {
use VerboseDecodeError::*;
let v = InvalidBoolValue(2);
assert_eq!(format!("InvalidBoolValue({})", 2), format!("{:?}", v));
}
#[test]
fn display() {
use VerboseDecodeError::*;
assert_eq!(
format!("DLT Verbose Message Field: Encountered an invalid typeinfo {:?} (contradicting or unknown)", [1,2,3,4]),
format!("{}", InvalidTypeInfo([1,2,3,4]))
);
assert_eq!(
format!("DLT Verbose Message Field: Encountered invalid bool value '{}' (only 0 or 1 are valid)", 2),
format!("{}", InvalidBoolValue(2))
);
{
let v = UnexpectedEndOfSliceError {
layer: Layer::DltHeader,
actual_size: 1,
minimum_size: 2,
};
assert_eq!(format!("{}", v), format!("{}", UnexpectedEndOfSlice(v)));
}
assert_eq!(
format!("DLT Verbose Message Field: Encountered a variable name string missing the terminating zero value"),
format!("{}", VariableNameStringMissingNullTermination)
);
assert_eq!(
format!("DLT Verbose Message Field: Encountered a variable unit string missing the terminating zero value"),
format!("{}", VariableUnitStringMissingNullTermination)
);
#[allow(invalid_from_utf8)]
{
let v = std::str::from_utf8(&[0, 159, 146, 150]).unwrap_err();
assert_eq!(format!("{}", v), format!("{}", Utf8(v)));
}
}
#[cfg(feature = "std")]
#[test]
#[allow(invalid_from_utf8)]
fn source() {
use std::error::Error;
use VerboseDecodeError::*;
assert!(InvalidTypeInfo([1, 2, 3, 4]).source().is_none());
assert!(InvalidBoolValue(2).source().is_none());
assert!(UnexpectedEndOfSlice(UnexpectedEndOfSliceError {
layer: Layer::DltHeader,
actual_size: 1,
minimum_size: 2,
})
.source()
.is_some());
assert!(VariableNameStringMissingNullTermination.source().is_none());
assert!(VariableUnitStringMissingNullTermination.source().is_none());
assert!(Utf8(std::str::from_utf8(&[0, 159, 146, 150]).unwrap_err())
.source()
.is_some());
}
#[test]
#[allow(invalid_from_utf8)]
fn from_utf8_error() {
let e: VerboseDecodeError = std::str::from_utf8(&[0, 159, 146, 150]).unwrap_err().into();
assert_matches!(e, VerboseDecodeError::Utf8(_));
}
}