use core::fmt;
use bacnet_npdu::{AddressField, MAX_MAC_LEN, Malformed};
use bacnet_types::error::{DecodeError, DecodingKind, Error, RangeError};
use super::NpduAddress;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NpduDecodeError {
AddressTooLong {
field: AddressField,
length: u8,
dnet: Option<u16>,
source: Option<NpduAddress>,
},
Malformed(Malformed),
}
impl fmt::Display for NpduDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AddressTooLong { field, length, .. } => write!(
f,
"NPDU {}={length} exceeds the {MAX_MAC_LEN}-octet address limit",
field.length_octet(),
),
Self::Malformed(fault) => fault.fmt(f),
}
}
}
impl core::error::Error for NpduDecodeError {}
impl From<NpduDecodeError> for Error {
fn from(error: NpduDecodeError) -> Self {
match error {
NpduDecodeError::AddressTooLong { field, length, .. } => {
let label = match field {
AddressField::Destination => "NPDU DLEN={} exceeds the {}-octet address limit",
AddressField::Source => "NPDU SLEN={} exceeds the {}-octet address limit",
};
RangeError::new(label)
.with_values(length.into(), MAX_MAC_LEN as u64)
.into()
}
NpduDecodeError::Malformed(fault) => {
let (kind, label) = match fault {
Malformed::Truncated => (DecodingKind::Missing, "NPDU truncated"),
Malformed::Version => (
DecodingKind::InvalidEncoding,
"unsupported BACnet protocol version",
),
Malformed::ReservedNetwork => (
DecodingKind::InvalidEncoding,
"NPDU names a reserved network number",
),
Malformed::EmptySource => (
DecodingKind::InvalidEncoding,
"NPDU source SLEN=0 is invalid",
),
_ => (DecodingKind::InvalidEncoding, "NPDU malformed"),
};
Error::Decoding(DecodeError::new(kind, 0, label))
}
}
}
}