Skip to main content

bacnet_encoding/apdu/
remote_error.rs

1//! How a refusal PDU reads as a [`RemoteError`] (#2026).
2//!
3//! The client's dispatch, its endpoint requester and the server's
4//! notification transactions all turn an Error, Reject or Abort PDU into the
5//! same [`RemoteError`]; these helpers are the one place that mapping lives.
6
7use bacnet_types::error::RemoteError;
8
9use super::{AbortPdu, Apdu, ErrorPdu, RejectPdu};
10
11impl ErrorPdu {
12    /// The refusal as a [`RemoteError::Error`]: the class and code.
13    ///
14    /// Any service-specific body after the class and code (`error_data`) is
15    /// not part of it; a caller that reports a structured error reads that
16    /// body itself.
17    #[must_use]
18    pub const fn remote_error(&self) -> RemoteError {
19        RemoteError::Error {
20            class: self.error_class,
21            code: self.error_code,
22        }
23    }
24}
25
26impl RejectPdu {
27    /// The refusal as a [`RemoteError::Reject`] carrying the reason.
28    #[must_use]
29    pub const fn remote_error(&self) -> RemoteError {
30        RemoteError::Reject {
31            reason: self.reject_reason,
32        }
33    }
34}
35
36impl AbortPdu {
37    /// The refusal as a [`RemoteError::Abort`] carrying the reason.
38    ///
39    /// It doesn't look at `sent_by_server`: whether an Abort may end a
40    /// transaction is the caller's decision.
41    #[must_use]
42    pub const fn remote_error(&self) -> RemoteError {
43        RemoteError::Abort {
44            reason: self.abort_reason,
45        }
46    }
47}
48
49impl Apdu {
50    /// How the peer turned the request down, for an Error, Reject or Abort
51    /// PDU; `None` for every other PDU type.
52    ///
53    /// A convenience for code holding an `Apdu` of unknown type; the stack's
54    /// own dispatch has already matched the PDU type and calls the
55    /// per-PDU `remote_error()` instead.
56    #[must_use]
57    pub const fn remote_error(&self) -> Option<RemoteError> {
58        match self {
59            Self::Error(pdu) => Some(pdu.remote_error()),
60            Self::Reject(pdu) => Some(pdu.remote_error()),
61            Self::Abort(pdu) => Some(pdu.remote_error()),
62            Self::ConfirmedRequest(_)
63            | Self::UnconfirmedRequest(_)
64            | Self::SimpleAck(_)
65            | Self::ComplexAck(_)
66            | Self::SegmentAck(_) => None,
67        }
68    }
69}