bacnet_rs/client/
error.rs1use crate::encoding::EncodingError;
9use crate::service::{AbortReason, RejectReason};
10use thiserror::Error;
11
12#[derive(Debug, Error)]
14pub enum ClientError {
15 #[error("I/O error: {0}")]
17 Io(#[from] std::io::Error),
18
19 #[error("encoding error: {0}")]
22 Encoding(#[from] EncodingError),
23
24 #[error("failed to decode response: {0}")]
26 Decode(String),
27
28 #[error("request timed out")]
30 Timeout,
31
32 #[error("no response from device")]
34 NoResponse,
35
36 #[error("request rejected: {0}")]
38 Rejected(RejectReason),
39
40 #[error("transaction aborted: {0}")]
42 Abort(AbortReason),
43
44 #[error("{}", describe_bacnet_error(*class, *code))]
47 PropertyError {
48 class: u32,
50 code: u32,
52 },
53
54 #[error("invalid address: {0}")]
56 AddressParse(String),
57}
58
59fn error_class_name(class: u32) -> Option<&'static str> {
61 Some(match class {
62 0 => "device",
63 1 => "object",
64 2 => "property",
65 3 => "resources",
66 4 => "security",
67 5 => "services",
68 6 => "vt",
69 7 => "communication",
70 _ => return None,
71 })
72}
73
74fn error_code_name(code: u32) -> Option<&'static str> {
77 Some(match code {
78 0 => "other",
79 9 => "invalid-data-type",
80 20 => "no-space-to-write-property",
81 23 => "object-deletion-not-permitted",
82 27 => "read-access-denied",
83 29 => "service-request-denied",
84 30 => "timeout",
85 31 => "unknown-object",
86 32 => "unknown-property",
87 37 => "value-out-of-range",
88 40 => "write-access-denied",
89 44 => "not-cov-property",
90 45 => "optional-functionality-not-supported",
91 47 => "datatype-not-supported",
92 50 => "property-is-not-an-array",
93 70 => "unknown-device",
94 _ => return None,
95 })
96}
97
98fn describe_bacnet_error(class: u32, code: u32) -> String {
101 let class_label = match error_class_name(class) {
102 Some(name) => format!("{name}[{class}]"),
103 None => format!("{class}"),
104 };
105 match error_code_name(code) {
106 Some(name) => format!("{name} (class {class_label}, code {code})"),
107 None => format!("BACnet error (class {class_label}, code {code})"),
108 }
109}