#[cfg(not(feature = "std"))]
use alloc::string::ToString;
use core::fmt;
use bacnet_types::error::Error;
use super::NpduAddress;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NpduAddressField {
Destination,
Source,
}
impl NpduAddressField {
pub fn length_octet(self) -> &'static str {
match self {
Self::Destination => "DLEN",
Self::Source => "SLEN",
}
}
}
impl fmt::Display for NpduAddressField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Destination => "destination",
Self::Source => "source",
})
}
}
#[derive(Debug)]
pub enum NpduDecodeError {
AddressTooLong {
field: NpduAddressField,
length: u8,
dnet: Option<u16>,
source: Option<NpduAddress>,
},
Malformed(Error),
}
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 {}-octet address limit",
field.length_octet(),
NpduAddress::MAX_MAC_LEN
),
Self::Malformed(error) => error.fmt(f),
}
}
}
impl core::error::Error for NpduDecodeError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
Self::AddressTooLong { .. } => None,
Self::Malformed(error) => Some(error),
}
}
}
impl From<Error> for NpduDecodeError {
fn from(error: Error) -> Self {
Self::Malformed(error)
}
}
impl From<NpduDecodeError> for Error {
fn from(error: NpduDecodeError) -> Self {
match error {
NpduDecodeError::AddressTooLong { .. } => Error::OutOfRange(error.to_string()),
NpduDecodeError::Malformed(error) => error,
}
}
}