Skip to content

Commit

Permalink
feat: rename Exception to ExceptionCode (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
CosminPerRam authored Sep 12, 2024
1 parent 089fb0f commit 7d5fadc
Show file tree
Hide file tree
Showing 14 changed files with 82 additions and 77 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

- Added `Exception::Custom`.
- Removed `TryFrom<u8>` and `#[repr(u8)]` for `Exception`.
- Renamed `Exception` to `ExceptionCode` to be more consistent with
`FunctionCode`.

## v0.14.1 (2024-09-10)

Expand Down
14 changes: 7 additions & 7 deletions examples/rtu-over-tcp-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct ExampleService {
impl tokio_modbus::server::Service for ExampleService {
type Request = SlaveRequest<'static>;
type Response = Response;
type Exception = Exception;
type Exception = ExceptionCode;
type Future = future::Ready<Result<Self::Response, Self::Exception>>;

fn call(&self, req: Self::Request) -> Self::Future {
Expand All @@ -55,7 +55,7 @@ impl tokio_modbus::server::Service for ExampleService {
.map(|_| Response::WriteSingleRegister(addr, value)),
_ => {
println!("SERVER: Exception::IllegalFunction - Unimplemented function code in request: {req:?}");
Err(Exception::IllegalFunction)
Err(ExceptionCode::IllegalFunction)
}
};
future::ready(res)
Expand Down Expand Up @@ -85,15 +85,15 @@ fn register_read(
registers: &HashMap<u16, u16>,
addr: u16,
cnt: u16,
) -> Result<Vec<u16>, Exception> {
) -> Result<Vec<u16>, ExceptionCode> {
let mut response_values = vec![0; cnt.into()];
for i in 0..cnt {
let reg_addr = addr + i;
if let Some(r) = registers.get(&reg_addr) {
response_values[i as usize] = *r;
} else {
println!("SERVER: Exception::IllegalDataAddress");
return Err(Exception::IllegalDataAddress);
return Err(ExceptionCode::IllegalDataAddress);
}
}

Expand All @@ -106,14 +106,14 @@ fn register_write(
registers: &mut HashMap<u16, u16>,
addr: u16,
values: &[u16],
) -> Result<(), Exception> {
) -> Result<(), ExceptionCode> {
for (i, value) in values.iter().enumerate() {
let reg_addr = addr + i as u16;
if let Some(r) = registers.get_mut(&reg_addr) {
*r = *value;
} else {
println!("SERVER: Exception::IllegalDataAddress");
return Err(Exception::IllegalDataAddress);
return Err(ExceptionCode::IllegalDataAddress);
}
}

Expand Down Expand Up @@ -180,7 +180,7 @@ async fn client_context(socket_addr: SocketAddr) {
println!("CLIENT: Reading nonexistent holding register address... (should return IllegalDataAddress)");
let response = ctx.read_holding_registers(0x100, 1).await.unwrap();
println!("CLIENT: The result is '{response:?}'");
assert!(matches!(response, Err(Exception::IllegalDataAddress)));
assert!(matches!(response, Err(ExceptionCode::IllegalDataAddress)));

println!("CLIENT: Done.")
},
Expand Down
8 changes: 4 additions & 4 deletions examples/rtu-server-address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct Service {
}

impl Service {
fn handle(&self, req: SlaveRequest<'_>) -> Result<Option<Response>, Exception> {
fn handle(&self, req: SlaveRequest<'_>) -> Result<Option<Response>, ExceptionCode> {
let SlaveRequest { slave, request } = req;
if slave != self.slave.into() {
// Filtering: Ignore requests with mismatching slave IDs.
Expand All @@ -24,15 +24,15 @@ impl Service {
registers[2] = 0x77;
Ok(Some(Response::ReadInputRegisters(registers)))
}
_ => Err(Exception::IllegalFunction),
_ => Err(ExceptionCode::IllegalFunction),
}
}
}

impl tokio_modbus::server::Service for Service {
type Request = SlaveRequest<'static>;
type Response = Option<Response>;
type Exception = Exception;
type Exception = ExceptionCode;
type Future = future::Ready<Result<Self::Response, Self::Exception>>;

fn call(&self, req: Self::Request) -> Self::Future {
Expand Down Expand Up @@ -72,7 +72,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("CLIENT: Reading with illegal function... (should return IllegalFunction)");
let response = ctx.read_holding_registers(0x100, 1).await.unwrap();
println!("CLIENT: The result is '{response:?}'");
assert!(matches!(response, Err(Exception::IllegalFunction)));
assert!(matches!(response, Err(ExceptionCode::IllegalFunction)));

println!("CLIENT: Done.");

Expand Down
6 changes: 3 additions & 3 deletions examples/rtu-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct Service;
impl tokio_modbus::server::Service for Service {
type Request = SlaveRequest<'static>;
type Response = Response;
type Exception = Exception;
type Exception = ExceptionCode;
type Future = future::Ready<Result<Self::Response, Self::Exception>>;

fn call(&self, req: Self::Request) -> Self::Future {
Expand All @@ -23,7 +23,7 @@ impl tokio_modbus::server::Service for Service {
future::ready(Ok(Response::ReadInputRegisters(registers)))
}
Request::ReadHoldingRegisters(_, _) => {
future::ready(Err(Exception::IllegalDataAddress))
future::ready(Err(ExceptionCode::IllegalDataAddress))
}
_ => unimplemented!(),
}
Expand Down Expand Up @@ -64,7 +64,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("CLIENT: Reading nonexistent holding register address... (should return IllegalDataAddress)");
let response = ctx.read_holding_registers(0x100, 1).await.unwrap();
println!("CLIENT: The result is '{response:?}'");
assert!(matches!(response, Err(Exception::IllegalDataAddress)));
assert!(matches!(response, Err(ExceptionCode::IllegalDataAddress)));

println!("CLIENT: Done.");
Ok(())
Expand Down
14 changes: 7 additions & 7 deletions examples/tcp-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct ExampleService {
impl tokio_modbus::server::Service for ExampleService {
type Request = Request<'static>;
type Response = Response;
type Exception = Exception;
type Exception = ExceptionCode;
type Future = future::Ready<Result<Self::Response, Self::Exception>>;

fn call(&self, req: Self::Request) -> Self::Future {
Expand All @@ -54,7 +54,7 @@ impl tokio_modbus::server::Service for ExampleService {
.map(|_| Response::WriteSingleRegister(addr, value)),
_ => {
println!("SERVER: Exception::IllegalFunction - Unimplemented function code in request: {req:?}");
Err(Exception::IllegalFunction)
Err(ExceptionCode::IllegalFunction)
}
};
future::ready(res)
Expand Down Expand Up @@ -84,15 +84,15 @@ fn register_read(
registers: &HashMap<u16, u16>,
addr: u16,
cnt: u16,
) -> Result<Vec<u16>, Exception> {
) -> Result<Vec<u16>, ExceptionCode> {
let mut response_values = vec![0; cnt.into()];
for i in 0..cnt {
let reg_addr = addr + i;
if let Some(r) = registers.get(&reg_addr) {
response_values[i as usize] = *r;
} else {
println!("SERVER: Exception::IllegalDataAddress");
return Err(Exception::IllegalDataAddress);
return Err(ExceptionCode::IllegalDataAddress);
}
}

Expand All @@ -105,14 +105,14 @@ fn register_write(
registers: &mut HashMap<u16, u16>,
addr: u16,
values: &[u16],
) -> Result<(), Exception> {
) -> Result<(), ExceptionCode> {
for (i, value) in values.iter().enumerate() {
let reg_addr = addr + i as u16;
if let Some(r) = registers.get_mut(&reg_addr) {
*r = *value;
} else {
println!("SERVER: Exception::IllegalDataAddress");
return Err(Exception::IllegalDataAddress);
return Err(ExceptionCode::IllegalDataAddress);
}
}

Expand Down Expand Up @@ -178,7 +178,7 @@ async fn client_context(socket_addr: SocketAddr) {
println!("CLIENT: Reading nonexistent holding register address... (should return IllegalDataAddress)");
let response = ctx.read_holding_registers(0x100, 1).await.unwrap();
println!("CLIENT: The result is '{response:?}'");
assert!(matches!(response, Err(Exception::IllegalDataAddress)));
assert!(matches!(response, Err(ExceptionCode::IllegalDataAddress)));

println!("CLIENT: Done.")
},
Expand Down
14 changes: 7 additions & 7 deletions examples/tls-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ struct ExampleService {
impl tokio_modbus::server::Service for ExampleService {
type Request = Request<'static>;
type Response = Response;
type Exception = Exception;
type Exception = ExceptionCode;
type Future = future::Ready<Result<Self::Response, Self::Exception>>;

fn call(&self, req: Self::Request) -> Self::Future {
Expand All @@ -116,7 +116,7 @@ impl tokio_modbus::server::Service for ExampleService {
.map(|_| Response::WriteSingleRegister(addr, value)),
_ => {
println!("SERVER: Exception::IllegalFunction - Unimplemented function code in request: {req:?}");
Err(Exception::IllegalFunction)
Err(ExceptionCode::IllegalFunction)
}
};
future::ready(res)
Expand Down Expand Up @@ -146,15 +146,15 @@ fn register_read(
registers: &HashMap<u16, u16>,
addr: u16,
cnt: u16,
) -> Result<Vec<u16>, Exception> {
) -> Result<Vec<u16>, ExceptionCode> {
let mut response_values = vec![0; cnt.into()];
for i in 0..cnt {
let reg_addr = addr + i;
if let Some(r) = registers.get(&reg_addr) {
response_values[i as usize] = *r;
} else {
println!("SERVER: Exception::IllegalDataAddress");
return Err(Exception::IllegalDataAddress);
return Err(ExceptionCode::IllegalDataAddress);
}
}

Expand All @@ -167,14 +167,14 @@ fn register_write(
registers: &mut HashMap<u16, u16>,
addr: u16,
values: &[u16],
) -> Result<(), Exception> {
) -> Result<(), ExceptionCode> {
for (i, value) in values.iter().enumerate() {
let reg_addr = addr + i as u16;
if let Some(r) = registers.get_mut(&reg_addr) {
*r = *value;
} else {
println!("SERVER: Exception::IllegalDataAddress");
return Err(Exception::IllegalDataAddress);
return Err(ExceptionCode::IllegalDataAddress);
}
}

Expand Down Expand Up @@ -287,7 +287,7 @@ async fn client_context(socket_addr: SocketAddr) {
println!("CLIENT: Reading nonexistent holding register address... (should return IllegalDataAddress)");
let response = ctx.read_holding_registers(0x100, 1).await.unwrap();
println!("CLIENT: The result is '{response:?}'");
assert!(matches!(response, Err(Exception::IllegalDataAddress)));
assert!(matches!(response, Err(ExceptionCode::IllegalDataAddress)));

println!("CLIENT: Done.")
},
Expand Down
8 changes: 4 additions & 4 deletions src/codec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ impl TryFrom<Bytes> for ExceptionResponse {
));
}
let function = fn_err_code - 0x80;
let exception = Exception::new(rdr.read_u8()?);
let exception = ExceptionCode::new(rdr.read_u8()?);
Ok(ExceptionResponse {
function: FunctionCode::new(function),
exception,
Expand Down Expand Up @@ -529,7 +529,7 @@ mod tests {
fn exception_response_into_bytes() {
let bytes: Bytes = ExceptionResponse {
function: FunctionCode::ReadHoldingRegisters,
exception: Exception::IllegalDataAddress,
exception: ExceptionCode::IllegalDataAddress,
}
.into();
assert_eq!(bytes[0], 0x83);
Expand All @@ -546,7 +546,7 @@ mod tests {
rsp,
ExceptionResponse {
function: FunctionCode::ReadHoldingRegisters,
exception: Exception::IllegalDataAddress,
exception: ExceptionCode::IllegalDataAddress,
}
);
}
Expand All @@ -557,7 +557,7 @@ mod tests {
let rsp_pdu: Bytes = Response::ReadCoils(vec![]).into();
let ex_pdu: Bytes = ExceptionResponse {
function: FunctionCode::ReadHoldingRegisters,
exception: Exception::ServerDeviceFailure,
exception: ExceptionCode::ServerDeviceFailure,
}
.into();

Expand Down
22 changes: 11 additions & 11 deletions src/frame/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ impl Response {

/// A server (slave) exception.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Exception {
pub enum ExceptionCode {
/// 0x01
IllegalFunction,
/// 0x02
Expand All @@ -413,9 +413,9 @@ pub enum Exception {
Custom(u8),
}

impl From<Exception> for u8 {
fn from(from: Exception) -> Self {
use crate::frame::Exception::*;
impl From<ExceptionCode> for u8 {
fn from(from: ExceptionCode) -> Self {
use crate::frame::ExceptionCode::*;
match from {
IllegalFunction => 0x01,
IllegalDataAddress => 0x02,
Expand All @@ -431,11 +431,11 @@ impl From<Exception> for u8 {
}
}

impl Exception {
/// Create a new [`Exception`] with `value`.
impl ExceptionCode {
/// Create a new [`ExceptionCode`] with `value`.
#[must_use]
pub const fn new(value: u8) -> Self {
use crate::frame::Exception::*;
use crate::frame::ExceptionCode::*;

match value {
0x01 => IllegalFunction,
Expand All @@ -452,7 +452,7 @@ impl Exception {
}

pub(crate) fn description(&self) -> &str {
use crate::frame::Exception::*;
use crate::frame::ExceptionCode::*;

match *self {
IllegalFunction => "Illegal function",
Expand All @@ -473,7 +473,7 @@ impl Exception {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExceptionResponse {
pub function: FunctionCode,
pub exception: Exception,
pub exception: ExceptionCode,
}

/// Represents a message from the client (slave) to the server (master).
Expand Down Expand Up @@ -537,13 +537,13 @@ impl From<ResponsePdu> for Result<Response, ExceptionResponse> {
}
}

impl fmt::Display for Exception {
impl fmt::Display for ExceptionCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description())
}
}

impl error::Error for Exception {
impl error::Error for ExceptionCode {
fn description(&self) -> &str {
self.description()
}
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ mod frame;
#[cfg(feature = "server")]
pub use self::frame::SlaveRequest;
pub use self::frame::{
Address, Exception, ExceptionResponse, FunctionCode, Quantity, Request, Response,
Address, ExceptionCode, ExceptionResponse, FunctionCode, Quantity, Request, Response,
};

/// Specialized [`std::result::Result`] type for type-checked responses of the _Modbus_ client API.
Expand All @@ -58,8 +58,8 @@ pub use self::frame::{
/// This [`Result`] type contains 2 layers of errors.
///
/// 1. [`Error`]: An unexpected protocol or network error that occurred during client/server communication.
/// 2. [`Exception`]: An error occurred on the _Modbus_ server.
pub type Result<T> = std::result::Result<std::result::Result<T, Exception>, Error>;
/// 2. [`ExceptionCode`]: An error occurred on the _Modbus_ server.
pub type Result<T> = std::result::Result<std::result::Result<T, ExceptionCode>, Error>;

mod service;

Expand Down
2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub mod sync {
///////////////////////////////////////////////////////////////////
/// Types
///////////////////////////////////////////////////////////////////
pub use crate::{Exception, ProtocolError, Request, Response, Slave, SlaveId};
pub use crate::{ExceptionCode, ProtocolError, Request, Response, Slave, SlaveId};

#[cfg(feature = "server")]
pub use crate::frame::SlaveRequest;
Expand Down
Loading

0 comments on commit 7d5fadc

Please sign in to comment.