///|
/// Return whether an error is recoverable by a retry policy.
pub fn is_retryable(error : ModbusError) -> Bool {
match error {
Incomplete | InvalidChecksum | InvalidMbap | Busy | NoResponse => true
_ => false
}
}
///|
pub fn is_client_input_error(error : ModbusError) -> Bool {
match error {
InvalidUnitId
| InvalidFunction
| InvalidAddress
| InvalidQuantity
| InvalidByteCount
| InvalidData
| InvalidLength => true
_ => false
}
}
///|
pub fn is_transport_error(error : ModbusError) -> Bool {
match error {
Incomplete
| InvalidChecksum
| InvalidAscii
| InvalidMbap
| InvalidTransaction
| NoResponse => true
_ => false
}
}
///|
pub fn exception_for_error(error : ModbusError) -> ExceptionCode {
match error {
InvalidFunction | Unsupported => IllegalFunction
InvalidAddress | UnitMismatch => IllegalDataAddress
InvalidQuantity | InvalidByteCount | InvalidData | InvalidLength =>
IllegalDataValue
Busy => ServerDeviceBusy
_ => ServerDeviceFailure
}
}
///|
pub fn safe_quantity(value : UInt16, limit : Int) -> Result[Int, ModbusError] {
if limit < 1 || value.to_int() < 1 || value.to_int() > limit {
Err(InvalidQuantity)
} else {
Ok(value.to_int())
}
}
///|
pub fn safe_address(
value : UInt16,
quantity : Int,
) -> Result[Unit, ModbusError] {
if valid_address_range(value, quantity) {
Ok(())
} else {
Err(InvalidAddress)
}
}
///|
pub fn bytes_equal(left : Array[Byte], right : Array[Byte]) -> Bool {
left == right
}
///|
pub fn byte_sum(bytes : Array[Byte]) -> Byte {
let mut sum : Byte = 0
for byte in bytes {
sum += byte
}
sum
}
///|
pub fn byte_xor(bytes : Array[Byte]) -> Byte {
let mut value : Byte = 0
for byte in bytes {
value = value ^ byte
}
value
}
///|
pub fn clamp_int(
value : Int,
minimum : Int,
maximum : Int,
) -> Result[Int, ModbusError] {
if minimum > maximum {
Err(InvalidData)
} else if value < minimum {
Ok(minimum)
} else if value > maximum {
Ok(maximum)
} else {
Ok(value)
}
}