use thiserror::Error;
#[derive(Debug, Error)]
pub enum ProtocolError {
#[error("Invalid command code: {code}")]
InvalidCommand { code: i32 },
#[error("Unsupported protocol version: {version}")]
UnsupportedVersion { version: i32 },
#[error("Missing required header field: {field}")]
HeaderMissing { field: &'static str },
#[error("Missing required message body")]
BodyMissing,
#[error("Checksum mismatch: expected {expected:x}, got {actual:x}")]
ChecksumMismatch { expected: u32, actual: u32 },
#[error("Invalid message format: {reason}")]
InvalidMessage { reason: String },
#[error("Protocol decode error: ext_fields_length={ext_fields_len}, header_length={header_len}")]
DecodeError { ext_fields_len: usize, header_len: usize },
#[error("Unsupported serialization type: {serialize_type}")]
UnsupportedSerializationType { serialize_type: u8 },
}
impl ProtocolError {
#[inline]
pub fn invalid_command(code: i32) -> Self {
Self::InvalidCommand { code }
}
#[inline]
pub fn header_missing(field: &'static str) -> Self {
Self::HeaderMissing { field }
}
#[inline]
pub fn checksum_mismatch(expected: u32, actual: u32) -> Self {
Self::ChecksumMismatch { expected, actual }
}
#[inline]
pub fn invalid_message(reason: impl Into<String>) -> Self {
Self::InvalidMessage { reason: reason.into() }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_protocol_error() {
let err = ProtocolError::invalid_command(999);
assert_eq!(err.to_string(), "Invalid command code: 999");
let err = ProtocolError::UnsupportedVersion { version: 1 };
assert_eq!(err.to_string(), "Unsupported protocol version: 1");
let err = ProtocolError::header_missing("topic");
assert_eq!(err.to_string(), "Missing required header field: topic");
let err = ProtocolError::BodyMissing;
assert_eq!(err.to_string(), "Missing required message body");
let err = ProtocolError::checksum_mismatch(0xABCD, 0x1234);
assert!(err.to_string().contains("abcd"));
assert!(err.to_string().contains("1234"));
let err = ProtocolError::invalid_message("too long");
assert_eq!(err.to_string(), "Invalid message format: too long");
let err = ProtocolError::DecodeError {
ext_fields_len: 10,
header_len: 20,
};
assert_eq!(
err.to_string(),
"Protocol decode error: ext_fields_length=10, header_length=20"
);
let err = ProtocolError::UnsupportedSerializationType { serialize_type: 2 };
assert_eq!(err.to_string(), "Unsupported serialization type: 2");
}
}