Skip to main content

rusty_modbus_frame/
frame.rs

1//! Unified frame type for decoded Modbus frames.
2
3use bytes::Bytes;
4use rusty_modbus_types::MbapHeader;
5
6/// A decoded Modbus frame from any transport.
7#[derive(Debug, Clone)]
8pub struct Frame {
9    /// Frame header (MBAP for TCP, unit ID for RTU).
10    pub header: FrameHeader,
11    /// PDU bytes (function code + data). Frozen `Bytes` handle — ref-counted, no copy.
12    pub pdu: Bytes,
13}
14
15/// Frame header discriminant — identifies the transport source.
16#[derive(Debug, Clone, Copy)]
17pub enum FrameHeader {
18    /// MBAP header from TCP transport.
19    Mbap(MbapHeader),
20    /// RTU header — just the unit ID (CRC already validated and stripped).
21    Rtu {
22        /// Unit/slave address byte.
23        unit_id: u8,
24    },
25}
26
27impl Frame {
28    /// Extract the unit ID from any frame header.
29    #[must_use]
30    pub fn unit_id(&self) -> u8 {
31        match &self.header {
32            FrameHeader::Mbap(h) => h.unit_id,
33            FrameHeader::Rtu { unit_id } => *unit_id,
34        }
35    }
36}
37
38/// RTU framing metadata (moved here from modbus-types per review finding #6).
39#[derive(Debug, Clone, Copy)]
40pub struct RtuFrameMeta {
41    /// Unit/slave address.
42    pub unit_id: u8,
43    /// PDU byte length (excluding unit ID and CRC).
44    pub pdu_length: usize,
45    /// CRC-16 value from the frame.
46    pub crc: u16,
47}