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}