1use core::fmt;
5#[cfg(feature = "std")]
6use std::error;
7
8use crate::{channel::Channel, packet::PacketType};
9
10#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
16pub enum DeviceError {
17 InvalidCommand,
19 InvalidParameter,
21 InvalidLength,
23 InvalidSequence,
25 MessageTimeout,
27 ChannelBusy,
29 LockRequired,
31 InvalidChannel,
33 Other,
35 Unknown(u8),
37}
38
39impl From<u8> for DeviceError {
40 fn from(error: u8) -> Self {
41 match error {
42 0x01 => Self::InvalidCommand,
43 0x02 => Self::InvalidParameter,
44 0x03 => Self::InvalidLength,
45 0x04 => Self::InvalidSequence,
46 0x05 => Self::MessageTimeout,
47 0x06 => Self::ChannelBusy,
48 0x0a => Self::LockRequired,
49 0x0b => Self::InvalidChannel,
50 0x7f => Self::Other,
51 error => Self::Unknown(error),
52 }
53 }
54}
55
56#[cfg(feature = "std")]
57impl error::Error for DeviceError {}
58
59impl fmt::Display for DeviceError {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 Self::InvalidCommand => "the command in the request is invalid".fmt(f),
63 Self::InvalidParameter => "the parameter(s) in the request is invalid".fmt(f),
64 Self::InvalidLength => "the length field is invalid for the request".fmt(f),
65 Self::InvalidSequence => "the sequence does not match expected value".fmt(f),
66 Self::MessageTimeout => "the message has timed out".fmt(f),
67 Self::ChannelBusy => "the device is busy for the requesting channel".fmt(f),
68 Self::LockRequired => "command requires channel lock".fmt(f),
69 Self::InvalidChannel => "CID is not valid".fmt(f),
70 Self::Other => "unspecified error".fmt(f),
71 Self::Unknown(value) => write!(f, "unknown error code 0x{:x}", value),
72 }
73 }
74}
75
76#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
78pub enum DefragmentationError {
79 InvalidChannel {
81 expected: Channel,
83 actual: Channel,
85 },
86 InvalidPacketType {
88 expected: PacketType,
90 actual: PacketType,
92 },
93 InvalidSequence {
95 expected: u8,
97 actual: u8,
99 },
100}
101
102#[cfg(feature = "std")]
103impl error::Error for DefragmentationError {}
104
105impl fmt::Display for DefragmentationError {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 match self {
108 Self::InvalidChannel { expected, actual } => {
109 write!(
110 f,
111 "expected a message with channel {} but got {}",
112 expected, actual
113 )
114 }
115 Self::InvalidPacketType { expected, actual } => {
116 write!(
117 f,
118 "expected a packet with type {:?} but got {:?}",
119 expected, actual
120 )
121 }
122 Self::InvalidSequence { expected, actual } => {
123 write!(
124 f,
125 "expected a message with sequence {} but got {}",
126 expected, actual
127 )
128 }
129 }
130 }
131}
132
133#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
135pub enum FragmentationError {
136 DataTooLong,
138 PacketSizeTooSmall,
140}
141
142#[cfg(feature = "std")]
143impl error::Error for FragmentationError {}
144
145impl fmt::Display for FragmentationError {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 match self {
148 Self::DataTooLong => "the message data is too long to be expressed in CTAPHID packets",
149 Self::PacketSizeTooSmall => "the packet size is too small to fit a CTAPHID packet",
150 }
151 .fmt(f)
152 }
153}
154
155#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
157pub enum ParseError {
158 NotEnoughData,
160 InvalidPacketType {
162 expected: PacketType,
164 actual: PacketType,
166 },
167 BufferCreationFailed,
169}
170
171#[cfg(feature = "std")]
172impl error::Error for ParseError {}
173
174impl fmt::Display for ParseError {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 match self {
177 Self::NotEnoughData => "there is not enough data for a CTAPHID packet".fmt(f),
178 Self::InvalidPacketType { expected, actual } => {
179 write!(
180 f,
181 "expected a {:?} packet but received a {:?} packet",
182 expected, actual
183 )
184 }
185 Self::BufferCreationFailed => "failed to create a buffer for the CTAPHID packet".fmt(f),
186 }
187 }
188}
189
190#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
192pub enum SerializationError {
193 BufferTooSmall,
195}
196
197#[cfg(feature = "std")]
198impl error::Error for SerializationError {}
199
200impl fmt::Display for SerializationError {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 match self {
203 Self::BufferTooSmall => "the buffer for serializing a CTAPHID packet is too small",
204 }
205 .fmt(f)
206 }
207}