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