From 1299c81b000e20b64972b945358b982a8a42aa39 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sun, 13 Oct 2024 19:03:08 +0200 Subject: [PATCH] Use newtype in RTU header --- src/codec/rtu.rs | 26 +++++++++++++++++--------- src/frame/mod.rs | 2 +- src/frame/rtu.rs | 17 +++++++++-------- src/service/rtu.rs | 4 +--- src/slave.rs | 12 ++++++------ 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/codec/rtu.rs b/src/codec/rtu.rs index 1978fd3..fe2dd19 100644 --- a/src/codec/rtu.rs +++ b/src/codec/rtu.rs @@ -10,7 +10,7 @@ use tokio_util::codec::{Decoder, Encoder}; use crate::{ bytes::{Buf, BufMut, Bytes, BytesMut}, frame::rtu::*, - slave::SlaveId, + Slave, SlaveId, }; use super::*; @@ -284,7 +284,9 @@ impl Decoder for ClientCodec { return Ok(None); }; - let hdr = Header { slave_id }; + let hdr = Header { + slave: Slave(slave_id), + }; // Decoding of the PDU is unlikely to fail due // to transmission errors, because the frame's bytes @@ -309,7 +311,9 @@ impl Decoder for ServerCodec { return Ok(None); }; - let hdr = Header { slave_id }; + let hdr = Header { + slave: Slave(slave_id), + }; // Decoding of the PDU is unlikely to fail due // to transmission errors, because the frame's bytes @@ -331,7 +335,7 @@ impl<'a> Encoder> for ClientCodec { let RequestAdu { hdr, pdu } = adu; let pdu_data: Bytes = pdu.try_into()?; buf.reserve(pdu_data.len() + 3); - buf.put_u8(hdr.slave_id); + buf.put_u8(hdr.slave.into()); buf.put_slice(&pdu_data); let crc = calc_crc(buf); buf.put_u16(crc); @@ -347,7 +351,7 @@ impl Encoder for ServerCodec { let ResponseAdu { hdr, pdu } = adu; let pdu_data: Bytes = pdu.into(); buf.reserve(pdu_data.len() + 3); - buf.put_u8(hdr.slave_id); + buf.put_u8(hdr.slave.into()); buf.put_slice(&pdu_data); let crc = calc_crc(buf); buf.put_u16(crc); @@ -651,7 +655,7 @@ mod tests { ); let ResponseAdu { hdr, pdu } = codec.decode(&mut buf).unwrap().unwrap(); assert_eq!(buf.len(), 1); - assert_eq!(hdr.slave_id, 0x01); + assert_eq!(hdr.slave, Slave(0x01)); if let Ok(Response::ReadHoldingRegisters(data)) = pdu.into() { assert_eq!(data.len(), 2); assert_eq!(data, vec![0x8902, 0x42C7]); @@ -682,7 +686,7 @@ mod tests { ); let ResponseAdu { hdr, pdu } = codec.decode(&mut buf).unwrap().unwrap(); assert_eq!(buf.len(), 1); - assert_eq!(hdr.slave_id, 0x01); + assert_eq!(hdr.slave, Slave(0x01)); if let Ok(Response::ReadHoldingRegisters(data)) = pdu.into() { assert_eq!(data.len(), 2); assert_eq!(data, vec![0x8902, 0x42C7]); @@ -720,7 +724,9 @@ mod tests { let req = Request::ReadHoldingRegisters(0x082b, 2); let pdu = req.into(); let slave_id = 0x01; - let hdr = Header { slave_id }; + let hdr = Header { + slave: Slave(slave_id), + }; let adu = RequestAdu { hdr, pdu }; codec.encode(adu, &mut buf).unwrap(); @@ -736,7 +742,9 @@ mod tests { let req = Request::ReadHoldingRegisters(0x082b, 2); let pdu = req.into(); let slave_id = 0x01; - let hdr = Header { slave_id }; + let hdr = Header { + slave: Slave(slave_id), + }; let adu = RequestAdu { hdr, pdu }; let mut buf = BytesMut::with_capacity(40); #[allow(unsafe_code)] diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 26ce98e..f2f4063 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -294,7 +294,7 @@ impl<'a> Request<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub struct SlaveRequest<'a> { /// Slave Id from the request - pub slave: crate::slave::SlaveId, + pub slave: crate::SlaveId, /// A `Request` enum pub request: Request<'a>, } diff --git a/src/frame/rtu.rs b/src/frame/rtu.rs index 0576928..1823371 100644 --- a/src/frame/rtu.rs +++ b/src/frame/rtu.rs @@ -3,7 +3,7 @@ use super::*; -use crate::{ProtocolError, Result, SlaveId}; +use crate::{ProtocolError, Result, Slave}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct RequestContext { @@ -20,7 +20,7 @@ impl RequestContext { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub(crate) struct Header { - pub(crate) slave_id: SlaveId, + pub(crate) slave: Slave, } #[derive(Debug, Clone)] @@ -92,9 +92,10 @@ impl<'a> From> for Request<'a> { #[cfg(feature = "server")] impl<'a> From> for SlaveRequest<'a> { fn from(from: RequestAdu<'a>) -> Self { + let RequestAdu { hdr, pdu } = from; Self { - slave: from.hdr.slave_id, - request: from.pdu.into(), + slave: hdr.slave.into(), + request: pdu.into(), } } } @@ -106,8 +107,8 @@ mod tests { #[test] fn validate_same_headers() { // Given - let req_hdr = Header { slave_id: 0 }; - let rsp_hdr = Header { slave_id: 0 }; + let req_hdr = Header { slave: Slave(0) }; + let rsp_hdr = Header { slave: Slave(0) }; // When let result = verify_response_header(&req_hdr, &rsp_hdr); @@ -119,8 +120,8 @@ mod tests { #[test] fn invalid_validate_not_same_slave_id() { // Given - let req_hdr = Header { slave_id: 0 }; - let rsp_hdr = Header { slave_id: 5 }; + let req_hdr = Header { slave: Slave(0) }; + let rsp_hdr = Header { slave: Slave(5) }; // When let result = verify_response_header(&req_hdr, &rsp_hdr); diff --git a/src/service/rtu.rs b/src/service/rtu.rs index f98645e..292c8a2 100644 --- a/src/service/rtu.rs +++ b/src/service/rtu.rs @@ -180,9 +180,7 @@ fn request_adu<'a, R>(server: Slave, request_pdu: R) -> RequestAdu<'a> where R: Into>, { - let hdr = Header { - slave_id: server.into(), - }; + let hdr = Header { slave: server }; let pdu = request_pdu.into(); RequestAdu { hdr, pdu } } diff --git a/src/slave.rs b/src/slave.rs index 9dc7765..6aedc84 100644 --- a/src/slave.rs +++ b/src/slave.rs @@ -9,7 +9,7 @@ use std::{fmt, num::ParseIntError, str::FromStr}; pub type SlaveId = u8; /// A single byte for addressing Modbus slave devices. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct Slave(pub SlaveId); @@ -101,7 +101,7 @@ impl FromStr for Slave { impl fmt::Display for Slave { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} (0x{:0>2X})", self.0, self.0) + write!(f, "{} (0x{:02X})", self.0, self.0) } } @@ -148,9 +148,9 @@ mod tests { } #[test] - fn format() { - assert!(format!("{}", Slave(123)).contains("123")); - assert!(format!("{}", Slave(0x7B)).contains("0x7B")); - assert!(!format!("{}", Slave(0x7B)).contains("0x7b")); + fn display() { + assert_eq!("0 (0x00)", Slave(0).to_string()); + assert_eq!("123 (0x7B)", Slave(123).to_string()); + assert_eq!("123 (0x7B)", Slave(0x7B).to_string()); } }