use core::fmt;
#[cfg(feature = "std")]
use std::error;
use crate::{channel::Channel, packet::PacketType};
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum DeviceError {
InvalidCommand,
InvalidParameter,
InvalidLength,
InvalidSequence,
MessageTimeout,
ChannelBusy,
LockRequired,
InvalidChannel,
Other,
Unknown(u8),
}
impl From<u8> for DeviceError {
fn from(error: u8) -> Self {
match error {
0x01 => Self::InvalidCommand,
0x02 => Self::InvalidParameter,
0x03 => Self::InvalidLength,
0x04 => Self::InvalidSequence,
0x05 => Self::MessageTimeout,
0x06 => Self::ChannelBusy,
0x0a => Self::LockRequired,
0x0b => Self::InvalidChannel,
0x7f => Self::Other,
error => Self::Unknown(error),
}
}
}
#[cfg(feature = "std")]
impl error::Error for DeviceError {}
impl fmt::Display for DeviceError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidCommand => "the command in the request is invalid".fmt(f),
Self::InvalidParameter => "the parameter(s) in the request is invalid".fmt(f),
Self::InvalidLength => "the length field is invalid for the request".fmt(f),
Self::InvalidSequence => "the sequence does not match expected value".fmt(f),
Self::MessageTimeout => "the message has timed out".fmt(f),
Self::ChannelBusy => "the device is busy for the requesting channel".fmt(f),
Self::LockRequired => "command requires channel lock".fmt(f),
Self::InvalidChannel => "CID is not valid".fmt(f),
Self::Other => "unspecified error".fmt(f),
Self::Unknown(value) => write!(f, "unknown error code 0x{:x}", value),
}
}
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum DefragmentationError {
InvalidChannel {
expected: Channel,
actual: Channel,
},
InvalidPacketType {
expected: PacketType,
actual: PacketType,
},
InvalidSequence {
expected: u8,
actual: u8,
},
}
#[cfg(feature = "std")]
impl error::Error for DefragmentationError {}
impl fmt::Display for DefragmentationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidChannel { expected, actual } => {
write!(
f,
"expected a message with channel {} but got {}",
expected, actual
)
}
Self::InvalidPacketType { expected, actual } => {
write!(
f,
"expected a packet with type {:?} but got {:?}",
expected, actual
)
}
Self::InvalidSequence { expected, actual } => {
write!(
f,
"expected a message with sequence {} but got {}",
expected, actual
)
}
}
}
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum FragmentationError {
DataTooLong,
PacketSizeTooSmall,
}
#[cfg(feature = "std")]
impl error::Error for FragmentationError {}
impl fmt::Display for FragmentationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::DataTooLong => "the message data is too long to be expressed in CTAPHID packets",
Self::PacketSizeTooSmall => "the packet size is too small to fit a CTAPHID packet",
}
.fmt(f)
}
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum ParseError {
NotEnoughData,
InvalidPacketType {
expected: PacketType,
actual: PacketType,
},
BufferCreationFailed,
}
#[cfg(feature = "std")]
impl error::Error for ParseError {}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotEnoughData => "there is not enough data for a CTAPHID packet".fmt(f),
Self::InvalidPacketType { expected, actual } => {
write!(
f,
"expected a {:?} packet but received a {:?} packet",
expected, actual
)
}
Self::BufferCreationFailed => "failed to create a buffer for the CTAPHID packet".fmt(f),
}
}
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum SerializationError {
BufferTooSmall,
}
#[cfg(feature = "std")]
impl error::Error for SerializationError {}
impl fmt::Display for SerializationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BufferTooSmall => "the buffer for serializing a CTAPHID packet is too small",
}
.fmt(f)
}
}