use core::fmt;
use crate::enums::{AbortReason, ErrorClass, ErrorCode, RejectReason};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
pub enum RemoteError {
#[error("{}", ProtocolText { class: *class, code: *code })]
Error {
class: ErrorClass,
code: ErrorCode,
},
#[error("BACnet reject: reason={}", reason.to_raw())]
Reject {
reason: RejectReason,
},
#[error("BACnet abort: reason={}", reason.to_raw())]
Abort {
reason: AbortReason,
},
}
pub(super) struct ProtocolText {
pub(super) class: ErrorClass,
pub(super) code: ErrorCode,
}
impl fmt::Display for ProtocolText {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn name(
f: &mut fmt::Formatter<'_>,
named: Option<&str>,
field: &str,
value: u16,
) -> fmt::Result {
let Some(named) = named else {
return write!(f, "{field}={value}");
};
for c in named.chars() {
let c = if c == '_' {
'-'
} else {
c.to_ascii_lowercase()
};
fmt::Write::write_char(f, c)?;
}
Ok(())
}
f.write_str("BACnet error: ")?;
name(f, self.class.name(), "class", self.class.to_raw())?;
f.write_str(" / ")?;
name(f, self.code.name(), "code", self.code.to_raw())
}
}