modbus_core/
error.rs

1// SPDX-FileCopyrightText: Copyright (c) 2018-2025 slowtec GmbH <post@slowtec.de>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use core::fmt;
5
6/// modbus-core Error
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum Error {
9    /// Invalid coil value
10    CoilValue(u16),
11    /// Invalid buffer size
12    BufferSize,
13    /// Invalid function code
14    FnCode(u8),
15    /// Invalid exception code
16    ExceptionCode(u8),
17    /// Invalid exception function code
18    ExceptionFnCode(u8),
19    /// Invalid CRC
20    Crc(u16, u16),
21    /// Invalid byte count
22    ByteCount(u8),
23    /// Length Mismatch
24    LengthMismatch(usize, usize),
25    /// Protocol not Modbus
26    ProtocolNotModbus(u16),
27}
28
29impl fmt::Display for Error {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        match self {
32            Self::CoilValue(v) => write!(f, "Invalid coil value: {v}"),
33            Self::BufferSize => write!(f, "Invalid buffer size"),
34            Self::FnCode(fn_code) => write!(f, "Invalid function code: 0x{fn_code:0>2X}"),
35            Self::ExceptionCode(code) => write!(f, "Invalid exception code:0x {code:0>2X}"),
36            Self::ExceptionFnCode(code) => {
37                write!(f, "Invalid exception function code:0x {code:0>2X}")
38            }
39            Self::Crc(expected, actual) => write!(
40                f,
41                "Invalid CRC: expected = 0x{expected:0>4X}, actual = 0x{actual:0>4X}"
42            ),
43            Self::ByteCount(cnt) => write!(f, "Invalid byte count: {cnt}"),
44            Self::LengthMismatch(length_field, pdu_len) => write!(
45                f,
46                "Length Mismatch: Length Field: {length_field}, PDU Len + 1: {pdu_len}"
47            ),
48            Self::ProtocolNotModbus(protocol_id) => {
49                write!(f, "Protocol not Modbus(0), received {protocol_id} instead")
50            }
51        }
52    }
53}
54
55#[cfg(all(feature = "defmt", target_os = "none"))]
56impl defmt::Format for Error {
57    fn format(&self, f: defmt::Formatter) {
58        match self {
59            Self::CoilValue(v) => defmt::write!(f, "Invalid coil value: {}", v),
60            Self::BufferSize => defmt::write!(f, "Invalid buffer size"),
61            Self::FnCode(fn_code) => defmt::write!(f, "Invalid function code: {=u8:#04x}", fn_code),
62            Self::ExceptionCode(code) => {
63                defmt::write!(f, "Invalid exception code: {=u8:#04x}", code)
64            }
65            Self::ExceptionFnCode(code) => {
66                defmt::write!(f, "Invalid exception function code: {=u8:#04x}", code)
67            }
68            Self::Crc(expected, actual) => defmt::write!(
69                f,
70                "Invalid CRC: expected = {=u16:#06x}, actual = {=u16:#06x}",
71                expected,
72                actual
73            ),
74            Self::ByteCount(cnt) => defmt::write!(f, "Invalid byte count: {}", cnt),
75            Self::LengthMismatch(length_field, pdu_len) => defmt::write!(
76                f,
77                "Length Mismatch: Length Field: {}, PDU Len + 1: {}",
78                length_field,
79                pdu_len
80            ),
81            Self::ProtocolNotModbus(protocol_id) => {
82                defmt::write!(
83                    f,
84                    "Protocol not Modbus(0), received {} instead",
85                    protocol_id
86                )
87            }
88        }
89    }
90}