do not use () as Err, clean up error handling
Some checks failed
Rust / build (pull_request) Failing after 1m15s
Some checks failed
Rust / build (pull_request) Failing after 1m15s
This commit is contained in:
parent
373d0efe55
commit
fe1aa3ebd1
|
@ -33,8 +33,12 @@ impl From<CommandCode> for u16 {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
|
||||
#[error("The command code {0} is not known.")]
|
||||
pub struct InvalidCommandCodeError(pub u16);
|
||||
|
||||
impl TryFrom<u16> for CommandCode {
|
||||
type Error = ();
|
||||
type Error = InvalidCommandCodeError;
|
||||
|
||||
/// Returns the enum value for the specified `u16` or `Error` if the code is unknown.
|
||||
fn try_from(value: u16) -> Result<Self, Self::Error> {
|
||||
|
@ -97,7 +101,7 @@ impl TryFrom<u16> for CommandCode {
|
|||
value if value == CommandCode::Utf8Data as u16 => {
|
||||
Ok(CommandCode::Utf8Data)
|
||||
}
|
||||
_ => Err(()),
|
||||
_ => Err(InvalidCommandCodeError(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
command_code::CommandCode,
|
||||
command_code::{CommandCode, InvalidCommandCodeError},
|
||||
commands::errors::{TryFromPacketError, TryIntoPacketError},
|
||||
compression::into_compressed,
|
||||
compression::into_decompressed,
|
||||
|
@ -83,10 +83,7 @@ impl TryFrom<Packet> for BitmapCommand {
|
|||
type Error = TryFromPacketError;
|
||||
|
||||
fn try_from(packet: Packet) -> Result<Self, Self::Error> {
|
||||
let code = CommandCode::try_from(packet.header.command_code).map_err(
|
||||
|()| TryFromPacketError::InvalidCommand(packet.header.command_code),
|
||||
)?;
|
||||
|
||||
let code = CommandCode::try_from(packet.header.command_code)?;
|
||||
match code {
|
||||
CommandCode::BitmapLinearWinUncompressed => {
|
||||
Self::packet_into_bitmap_win(
|
||||
|
@ -111,9 +108,9 @@ impl TryFrom<Packet> for BitmapCommand {
|
|||
Self::packet_into_bitmap_win(packet, CompressionCode::Zstd)
|
||||
}
|
||||
|
||||
_ => Err(TryFromPacketError::InvalidCommand(
|
||||
packet.header.command_code,
|
||||
)),
|
||||
_ => {
|
||||
Err(InvalidCommandCodeError(packet.header.command_code).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -182,9 +179,7 @@ mod tests {
|
|||
..Default::default()
|
||||
}
|
||||
}),
|
||||
Err(TryFromPacketError::InvalidCommand(
|
||||
CommandCode::Brightness.into()
|
||||
))
|
||||
Err(InvalidCommandCodeError(CommandCode::Brightness.into()).into())
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::{
|
||||
command_code::CommandCode, commands::errors::TryFromPacketError,
|
||||
compression::into_compressed, compression::into_decompressed, BitVec,
|
||||
CompressionCode, Header, Offset, Packet, TryIntoPacketError, TypedCommand,
|
||||
command_code::CommandCode, command_code::InvalidCommandCodeError,
|
||||
commands::errors::TryFromPacketError, compression::into_compressed,
|
||||
compression::into_decompressed, BitVec, CompressionCode, Header, Offset,
|
||||
Packet, TryIntoPacketError, TypedCommand,
|
||||
};
|
||||
|
||||
/// Binary operations for use with the [`BitVecCommand`] command.
|
||||
|
@ -86,29 +87,21 @@ impl TryFrom<Packet> for BitVecCommand {
|
|||
},
|
||||
payload,
|
||||
} = packet;
|
||||
let command_code = CommandCode::try_from(command_code)
|
||||
.map_err(|()| TryFromPacketError::InvalidCommand(command_code))?;
|
||||
let command_code = CommandCode::try_from(command_code)?;
|
||||
let operation = match command_code {
|
||||
CommandCode::BitmapLinear => BinaryOperation::Overwrite,
|
||||
CommandCode::BitmapLinearAnd => BinaryOperation::And,
|
||||
CommandCode::BitmapLinearOr => BinaryOperation::Or,
|
||||
CommandCode::BitmapLinearXor => BinaryOperation::Xor,
|
||||
_ => {
|
||||
return Err(TryFromPacketError::InvalidCommand(
|
||||
command_code.into(),
|
||||
))
|
||||
return Err(InvalidCommandCodeError(command_code.into()).into());
|
||||
}
|
||||
};
|
||||
|
||||
if reserved != 0 {
|
||||
return Err(TryFromPacketError::ExtraneousHeaderValues);
|
||||
}
|
||||
let compression = match CompressionCode::try_from(sub) {
|
||||
Err(()) => {
|
||||
return Err(TryFromPacketError::InvalidCompressionCode(sub));
|
||||
}
|
||||
Ok(value) => value,
|
||||
};
|
||||
let compression = CompressionCode::try_from(sub)?;
|
||||
let payload = match into_decompressed(compression, payload) {
|
||||
None => return Err(TryFromPacketError::DecompressionFailed),
|
||||
Some(value) => value,
|
||||
|
@ -138,6 +131,7 @@ impl From<BitVecCommand> for TypedCommand {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::commands::tests::{round_trip, TestImplementsCommand};
|
||||
use crate::compression_code::InvalidCompressionCodeError;
|
||||
use crate::{commands, Bitmap, BitmapCommand, Origin};
|
||||
|
||||
impl TestImplementsCommand for BitVecCommand {}
|
||||
|
@ -152,9 +146,7 @@ mod tests {
|
|||
..Default::default()
|
||||
}
|
||||
}),
|
||||
Err(TryFromPacketError::InvalidCommand(
|
||||
CommandCode::Brightness.into()
|
||||
))
|
||||
Err(InvalidCommandCodeError(CommandCode::Brightness.into()).into())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -285,7 +277,7 @@ mod tests {
|
|||
};
|
||||
assert_eq!(
|
||||
TypedCommand::try_from(p),
|
||||
Err(TryFromPacketError::InvalidCompressionCode(42))
|
||||
Err(InvalidCompressionCodeError(42).into())
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
command_code::CommandCode, commands::check_command_code_only,
|
||||
commands::errors::TryFromPacketError, Packet, TypedCommand,
|
||||
command_code::CommandCode,
|
||||
commands::{check_command_code_only, errors::TryFromPacketError},
|
||||
Packet, TypedCommand,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -43,6 +44,7 @@ impl From<ClearCommand> for TypedCommand {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::command_code::InvalidCommandCodeError;
|
||||
use crate::commands::tests::TestImplementsCommand;
|
||||
use crate::Header;
|
||||
|
||||
|
@ -85,9 +87,7 @@ mod tests {
|
|||
payload: vec![],
|
||||
};
|
||||
assert_eq!(
|
||||
Err(TryFromPacketError::InvalidCommand(
|
||||
CommandCode::HardReset.into()
|
||||
)),
|
||||
Err(InvalidCommandCodeError(CommandCode::HardReset.into()).into()),
|
||||
ClearCommand::try_from(p)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
use crate::LoadBitmapError;
|
||||
use crate::{
|
||||
command_code::InvalidCommandCodeError,
|
||||
compression_code::InvalidCompressionCodeError, LoadBitmapError,
|
||||
};
|
||||
use std::num::TryFromIntError;
|
||||
|
||||
/// Err values for [`crate::TypedCommand::try_from`].
|
||||
#[derive(Debug, PartialEq, thiserror::Error)]
|
||||
pub enum TryFromPacketError {
|
||||
/// the contained command code does not correspond to a known command
|
||||
#[error("The command code {0:?} does not correspond to a known command")]
|
||||
InvalidCommand(u16),
|
||||
#[error(transparent)]
|
||||
InvalidCommand(#[from] InvalidCommandCodeError),
|
||||
/// the expected payload size was n, but size m was found
|
||||
#[error("the expected payload size was {0}, but size {1} was found")]
|
||||
UnexpectedPayloadSize(usize, usize),
|
||||
|
@ -16,8 +19,8 @@ pub enum TryFromPacketError {
|
|||
#[error("Header fields not needed for the command have been used")]
|
||||
ExtraneousHeaderValues,
|
||||
/// The contained compression code is not known. This could be of disabled features.
|
||||
#[error("The compression code {0:?} does not correspond to a known compression algorithm.")]
|
||||
InvalidCompressionCode(u16),
|
||||
#[error(transparent)]
|
||||
InvalidCompression(#[from] InvalidCompressionCodeError),
|
||||
/// Decompression of the payload failed. This can be caused by corrupted packets.
|
||||
#[error("The decompression of the payload failed")]
|
||||
DecompressionFailed,
|
||||
|
|
|
@ -11,7 +11,7 @@ mod fade_out;
|
|||
mod hard_reset;
|
||||
mod typed;
|
||||
|
||||
use crate::command_code::CommandCode;
|
||||
use crate::command_code::{CommandCode, InvalidCommandCodeError};
|
||||
use crate::{Header, Packet};
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -99,9 +99,7 @@ fn check_command_code_only(
|
|||
payload,
|
||||
} = packet;
|
||||
if packet.header.command_code != u16::from(code) {
|
||||
Some(TryFromPacketError::InvalidCommand(
|
||||
packet.header.command_code,
|
||||
))
|
||||
Some(InvalidCommandCodeError(packet.header.command_code).into())
|
||||
} else if !payload.is_empty() {
|
||||
Some(TryFromPacketError::UnexpectedPayloadSize(0, payload.len()))
|
||||
} else if a != 0 || b != 0 || c != 0 || d != 0 {
|
||||
|
@ -114,11 +112,11 @@ fn check_command_code_only(
|
|||
fn check_command_code(
|
||||
actual: u16,
|
||||
expected: CommandCode,
|
||||
) -> Result<(), TryFromPacketError> {
|
||||
) -> Result<(), InvalidCommandCodeError> {
|
||||
if actual == u16::from(expected) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(TryFromPacketError::InvalidCommand(actual))
|
||||
Err(InvalidCommandCodeError(actual))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,6 +124,10 @@ fn check_command_code(
|
|||
mod tests {
|
||||
use crate::*;
|
||||
|
||||
#[allow(
|
||||
unused,
|
||||
reason = "false positive, used in submodules that check if structs impl Command"
|
||||
)]
|
||||
pub(crate) trait TestImplementsCommand: Command {}
|
||||
|
||||
pub(crate) fn round_trip(original: TypedCommand) {
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
command_code::CommandCode, commands::errors::TryFromPacketError,
|
||||
BitVecCommand, BitmapCommand, BrightnessCommand, BrightnessGridCommand,
|
||||
CharGridCommand, ClearCommand, Cp437GridCommand, FadeOutCommand,
|
||||
HardResetCommand, Header, Packet, TryIntoPacketError,
|
||||
HardResetCommand, Packet, TryIntoPacketError,
|
||||
};
|
||||
|
||||
/// This enum contains all commands provided by the library.
|
||||
|
@ -31,18 +31,7 @@ impl TryFrom<Packet> for TypedCommand {
|
|||
|
||||
/// Try to interpret the [Packet] as one containing a [Command]
|
||||
fn try_from(packet: Packet) -> Result<Self, Self::Error> {
|
||||
let Packet {
|
||||
header: Header { command_code, .. },
|
||||
..
|
||||
} = packet;
|
||||
let command_code = match CommandCode::try_from(command_code) {
|
||||
Err(()) => {
|
||||
return Err(TryFromPacketError::InvalidCommand(command_code));
|
||||
}
|
||||
Ok(value) => value,
|
||||
};
|
||||
|
||||
Ok(match command_code {
|
||||
Ok(match CommandCode::try_from(packet.header.command_code)? {
|
||||
CommandCode::Clear => {
|
||||
TypedCommand::Clear(crate::ClearCommand::try_from(packet)?)
|
||||
}
|
||||
|
@ -119,9 +108,10 @@ impl TryFrom<TypedCommand> for Packet {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::commands::errors::TryFromPacketError;
|
||||
use crate::commands::tests::TestImplementsCommand;
|
||||
use crate::{Header, Packet, TypedCommand};
|
||||
use crate::{
|
||||
command_code::InvalidCommandCodeError,
|
||||
commands::tests::TestImplementsCommand, Header, Packet, TypedCommand,
|
||||
};
|
||||
|
||||
impl TestImplementsCommand for TypedCommand {}
|
||||
|
||||
|
@ -138,9 +128,6 @@ mod tests {
|
|||
payload: vec![],
|
||||
};
|
||||
let result = TypedCommand::try_from(p);
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(TryFromPacketError::InvalidCommand(0xFF))
|
||||
));
|
||||
assert_eq!(result, Err(InvalidCommandCodeError(0xFF).into()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,10 @@ impl CompressionCode {
|
|||
];
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
|
||||
#[error("The compression code {0} is not known.")]
|
||||
pub struct InvalidCompressionCodeError(pub u16);
|
||||
|
||||
impl From<CompressionCode> for u16 {
|
||||
fn from(value: CompressionCode) -> Self {
|
||||
value as u16
|
||||
|
@ -61,7 +65,7 @@ impl From<CompressionCode> for u16 {
|
|||
}
|
||||
|
||||
impl TryFrom<u16> for CompressionCode {
|
||||
type Error = ();
|
||||
type Error = InvalidCompressionCodeError;
|
||||
|
||||
fn try_from(value: u16) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
|
@ -84,7 +88,7 @@ impl TryFrom<u16> for CompressionCode {
|
|||
value if value == CompressionCode::Zstd as u16 => {
|
||||
Ok(CompressionCode::Zstd)
|
||||
}
|
||||
_ => Err(()),
|
||||
_ => Err(InvalidCompressionCodeError(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,15 +92,19 @@ impl From<Packet> for Vec<u8> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
|
||||
#[error("The provided slice is smaller than the header size, so it cannot be read as a packet.")]
|
||||
pub struct SliceSmallerThanHeader;
|
||||
|
||||
impl TryFrom<&[u8]> for Packet {
|
||||
type Error = ();
|
||||
type Error = SliceSmallerThanHeader;
|
||||
|
||||
/// Tries to interpret the bytes as a [Packet].
|
||||
///
|
||||
/// returns: `Error` if slice is not long enough to be a [Packet]
|
||||
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
|
||||
if value.len() < size_of::<Header>() {
|
||||
return Err(());
|
||||
return Err(SliceSmallerThanHeader);
|
||||
}
|
||||
|
||||
let header = {
|
||||
|
@ -124,7 +128,7 @@ impl TryFrom<&[u8]> for Packet {
|
|||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for Packet {
|
||||
type Error = ();
|
||||
type Error = SliceSmallerThanHeader;
|
||||
|
||||
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
Self::try_from(value.as_slice())
|
||||
|
@ -203,6 +207,9 @@ mod tests {
|
|||
#[test]
|
||||
fn too_small() {
|
||||
let data = vec![0u8; 4];
|
||||
assert_eq!(Packet::try_from(data.as_slice()), Err(()));
|
||||
assert_eq!(
|
||||
Packet::try_from(data.as_slice()),
|
||||
Err(SliceSmallerThanHeader)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue