1use crate::instructions::packet_id::BROADCAST;
2
3#[derive(Debug)]
5pub enum InitializeError {
6 GetConfiguration(std::io::Error),
8
9 GetBaudRate(std::io::Error),
11}
12
13#[derive(Debug)]
15pub enum TransferError {
16 WriteError(WriteError),
18
19 ReadError(ReadError),
21}
22
23#[derive(Debug)]
25pub enum WriteError {
26 BufferTooSmall(BufferTooSmallError),
28
29 DiscardBuffer(std::io::Error),
31
32 Write(std::io::Error),
34}
35
36#[derive(Debug)]
41pub struct BufferTooSmallError {
42 pub required_size: usize,
44
45 pub total_size: usize,
47}
48
49#[derive(Debug)]
51pub enum ReadError {
52 BufferFull(BufferTooSmallError),
54
55 Io(std::io::Error),
57
58 InvalidMessage(InvalidMessage),
60
61 MotorError(MotorError),
68}
69
70#[derive(Debug, Clone, Eq, PartialEq)]
72pub enum InvalidMessage {
73 InvalidHeaderPrefix(InvalidHeaderPrefix),
75
76 InvalidChecksum(InvalidChecksum),
78
79 InvalidPacketId(InvalidPacketId),
81
82 InvalidInstruction(InvalidInstruction),
84
85 InvalidParameterCount(InvalidParameterCount),
87}
88
89#[derive(Clone, Eq, PartialEq)]
91pub struct MotorError {
92 pub raw: u8,
94}
95
96impl MotorError {
97 pub fn error_number(&self) -> u8 {
101 self.raw & !0x80
102 }
103
104 pub fn alert(&self) -> bool {
111 self.raw & 0x80 != 0
112 }
113}
114
115impl std::fmt::Debug for MotorError {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 f.debug_struct("MotorError")
118 .field("error_number", &self.error_number())
119 .field("alert", &self.alert())
120 .finish()
121 }
122}
123
124#[derive(Debug, Clone, Eq, PartialEq)]
126pub struct InvalidHeaderPrefix {
127 pub actual: [u8; 4],
129
130 pub expected: [u8; 4],
132}
133
134#[derive(Debug, Clone, Eq, PartialEq)]
136pub struct InvalidChecksum {
137 pub message: u16,
139
140 pub computed: u16,
142}
143
144#[derive(Debug, Clone, Eq, PartialEq)]
146pub struct InvalidPacketId {
147 pub actual: u8,
149
150 pub expected: Option<u8>,
152}
153
154#[derive(Debug, Clone, Eq, PartialEq)]
156pub struct InvalidInstruction {
157 pub actual: u8,
159
160 pub expected: u8,
162}
163
164#[derive(Debug, Clone, Eq, PartialEq)]
166pub enum ExpectedCount {
167 Exact(usize),
169
170 Max(usize),
172}
173
174#[derive(Debug, Clone, Eq, PartialEq)]
176pub struct InvalidParameterCount {
177 pub actual: usize,
179
180 pub expected: ExpectedCount,
182}
183
184impl BufferTooSmallError {
185 pub fn check(required_size: usize, total_size: usize) -> Result<(), Self> {
187 if required_size <= total_size {
188 Ok(())
189 } else {
190 Err(Self { required_size, total_size })
191 }
192 }
193}
194
195impl MotorError {
196 pub fn check(raw: u8) -> Result<(), Self> {
201 if raw & !0x80 == 0 {
204 Ok(())
205 } else {
206 Err(Self { raw })
207 }
208 }
209}
210
211impl InvalidHeaderPrefix {
212 pub fn check(actual: &[u8], expected: [u8; 4]) -> Result<(), Self> {
214 if actual == expected {
215 Ok(())
216 } else {
217 Err(Self {
218 actual: [actual[0], actual[1], actual[2], actual[3]],
219 expected,
220 })
221 }
222 }
223}
224
225impl InvalidPacketId {
226 pub fn check(actual: u8, expected: u8) -> Result<(), Self> {
228 if actual == expected {
229 Ok(())
230 } else {
231 Err(Self {
232 actual,
233 expected: Some(expected),
234 })
235 }
236 }
237
238 pub fn check_ignore_broadcast(actual: u8, expected: u8) -> Result<(), Self> {
240 if expected == BROADCAST {
241 Ok(())
242 } else {
243 Self::check(actual, expected)
244 }
245 }
246}
247
248impl InvalidInstruction {
249 pub fn check(actual: u8, expected: u8) -> Result<(), Self> {
251 if actual == expected {
252 Ok(())
253 } else {
254 Err(Self { actual, expected })
255 }
256 }
257}
258
259impl InvalidParameterCount {
260 pub fn check(actual: usize, expected: usize) -> Result<(), Self> {
262 if actual == expected {
263 Ok(())
264 } else {
265 Err(Self {
266 actual,
267 expected: ExpectedCount::Exact(expected),
268 })
269 }
270 }
271
272 pub fn check_max(actual: usize, max: usize) -> Result<(), Self> {
274 if actual <= max {
275 Ok(())
276 } else {
277 Err(Self {
278 actual,
279 expected: ExpectedCount::Max(max),
280 })
281 }
282 }
283}
284
285impl std::error::Error for InitializeError {}
286impl std::error::Error for TransferError {}
287impl std::error::Error for WriteError {}
288impl std::error::Error for ReadError {}
289impl std::error::Error for InvalidMessage {}
290impl std::error::Error for MotorError {}
291impl std::error::Error for InvalidHeaderPrefix {}
292impl std::error::Error for InvalidChecksum {}
293impl std::error::Error for InvalidPacketId {}
294impl std::error::Error for InvalidInstruction {}
295impl std::error::Error for InvalidParameterCount {}
296
297impl From<WriteError> for TransferError {
298 fn from(other: WriteError) -> Self {
299 Self::WriteError(other)
300 }
301}
302
303impl From<ReadError> for TransferError {
304 fn from(other: ReadError) -> Self {
305 Self::ReadError(other)
306 }
307}
308
309impl From<InvalidMessage> for TransferError {
310 fn from(other: InvalidMessage) -> Self {
311 Self::ReadError(other.into())
312 }
313}
314
315impl From<InvalidHeaderPrefix> for TransferError {
316 fn from(other: InvalidHeaderPrefix) -> Self {
317 Self::ReadError(other.into())
318 }
319}
320
321impl From<InvalidChecksum> for TransferError {
322 fn from(other: InvalidChecksum) -> Self {
323 Self::ReadError(other.into())
324 }
325}
326
327impl From<InvalidPacketId> for TransferError {
328 fn from(other: InvalidPacketId) -> Self {
329 Self::ReadError(other.into())
330 }
331}
332
333impl From<InvalidInstruction> for TransferError {
334 fn from(other: InvalidInstruction) -> Self {
335 Self::ReadError(other.into())
336 }
337}
338
339impl From<InvalidParameterCount> for TransferError {
340 fn from(other: InvalidParameterCount) -> Self {
341 Self::ReadError(other.into())
342 }
343}
344
345impl From<BufferTooSmallError> for WriteError {
346 fn from(other: BufferTooSmallError) -> Self {
347 Self::BufferTooSmall(other)
348 }
349}
350
351impl From<BufferTooSmallError> for ReadError {
352 fn from(other: BufferTooSmallError) -> Self {
353 Self::BufferFull(other)
354 }
355}
356
357impl From<std::io::Error> for ReadError {
358 fn from(other: std::io::Error) -> Self {
359 Self::Io(other)
360 }
361}
362
363impl From<std::io::ErrorKind> for ReadError {
364 fn from(other: std::io::ErrorKind) -> Self {
365 Self::Io(other.into())
366 }
367}
368
369impl From<InvalidMessage> for ReadError {
370 fn from(other: InvalidMessage) -> Self {
371 Self::InvalidMessage(other)
372 }
373}
374
375impl From<MotorError> for ReadError {
376 fn from(other: MotorError) -> Self {
377 Self::MotorError(other)
378 }
379}
380
381impl From<InvalidHeaderPrefix> for ReadError {
382 fn from(other: InvalidHeaderPrefix) -> Self {
383 Self::InvalidMessage(other.into())
384 }
385}
386
387impl From<InvalidChecksum> for ReadError {
388 fn from(other: InvalidChecksum) -> Self {
389 Self::InvalidMessage(other.into())
390 }
391}
392
393impl From<InvalidPacketId> for ReadError {
394 fn from(other: InvalidPacketId) -> Self {
395 Self::InvalidMessage(other.into())
396 }
397}
398
399impl From<InvalidInstruction> for ReadError {
400 fn from(other: InvalidInstruction) -> Self {
401 Self::InvalidMessage(other.into())
402 }
403}
404
405impl From<InvalidParameterCount> for ReadError {
406 fn from(other: InvalidParameterCount) -> Self {
407 Self::InvalidMessage(other.into())
408 }
409}
410
411impl From<InvalidHeaderPrefix> for InvalidMessage {
412 fn from(other: InvalidHeaderPrefix) -> Self {
413 Self::InvalidHeaderPrefix(other)
414 }
415}
416
417impl From<InvalidChecksum> for InvalidMessage {
418 fn from(other: InvalidChecksum) -> Self {
419 Self::InvalidChecksum(other)
420 }
421}
422
423impl From<InvalidPacketId> for InvalidMessage {
424 fn from(other: InvalidPacketId) -> Self {
425 Self::InvalidPacketId(other)
426 }
427}
428
429impl From<InvalidInstruction> for InvalidMessage {
430 fn from(other: InvalidInstruction) -> Self {
431 Self::InvalidInstruction(other)
432 }
433}
434
435impl From<InvalidParameterCount> for InvalidMessage {
436 fn from(other: InvalidParameterCount) -> Self {
437 Self::InvalidParameterCount(other)
438 }
439}
440
441impl std::fmt::Display for InitializeError {
442 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
443 match self {
444 Self::GetConfiguration(e) => write!(f, "failed to get configuration of serial port: {e}"),
445 Self::GetBaudRate(e) => write!(f, "failed to get baud rate of serial port: {e}"),
446 }
447 }
448}
449
450impl std::fmt::Display for TransferError {
451 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
452 match self {
453 Self::WriteError(e) => write!(f, "{}", e),
454 Self::ReadError(e) => write!(f, "{}", e),
455 }
456 }
457}
458
459impl std::fmt::Display for WriteError {
460 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
461 match self {
462 Self::BufferTooSmall(e) => write!(
463 f,
464 "write buffer is too small: need {} bytes, but the size is {}",
465 e.required_size, e.total_size
466 ),
467 Self::DiscardBuffer(e) => write!(f, "failed to discard input buffer: {}", e),
468 Self::Write(e) => write!(f, "failed to write to serial port: {}", e),
469 }
470 }
471}
472
473impl std::fmt::Display for BufferTooSmallError {
474 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
475 write!(
476 f,
477 "buffer is too small: need {} bytes, but the size is {}",
478 self.required_size, self.total_size
479 )
480 }
481}
482
483impl std::fmt::Display for ReadError {
484 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
485 match self {
486 Self::BufferFull(e) => write!(
487 f,
488 "read buffer is too small: need {} bytes, but the size is {}",
489 e.required_size, e.total_size
490 ),
491 Self::Io(e) => write!(f, "failed to read from serial port: {}", e),
492 Self::InvalidMessage(e) => write!(f, "{}", e),
493 Self::MotorError(e) => write!(f, "{}", e),
494 }
495 }
496}
497
498impl std::fmt::Display for InvalidMessage {
499 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
500 match self {
501 Self::InvalidHeaderPrefix(e) => write!(f, "{}", e),
502 Self::InvalidChecksum(e) => write!(f, "{}", e),
503 Self::InvalidPacketId(e) => write!(f, "{}", e),
504 Self::InvalidInstruction(e) => write!(f, "{}", e),
505 Self::InvalidParameterCount(e) => write!(f, "{}", e),
506 }
507 }
508}
509
510impl std::fmt::Display for MotorError {
511 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
512 write!(f, "motor reported error status: {:#02X}", self.raw,)
513 }
514}
515
516impl std::fmt::Display for InvalidHeaderPrefix {
517 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
518 write!(
519 f,
520 "invalid header prefix, expected {:02X?}, got {:02X?}",
521 self.expected, self.actual
522 )
523 }
524}
525
526impl std::fmt::Display for InvalidChecksum {
527 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
528 write!(
529 f,
530 "invalid checksum, message claims {:#02X}, computed {:#02X}",
531 self.message, self.computed
532 )
533 }
534}
535
536impl std::fmt::Display for InvalidPacketId {
537 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
538 if let Some(expected) = self.expected {
539 write!(f, "invalid packet ID, expected {:#02X}, got {:#02X}", expected, self.actual)
540 } else {
541 write!(f, "invalid packet ID: {:#02X}", self.actual)
542 }
543 }
544}
545
546impl std::fmt::Display for InvalidInstruction {
547 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
548 write!(
549 f,
550 "invalid instruction ID, expected {:#02X}, got {:#02X}",
551 self.expected, self.actual
552 )
553 }
554}
555
556impl std::fmt::Display for ExpectedCount {
557 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
558 match self {
559 Self::Exact(x) => write!(f, "exactly {}", x),
560 Self::Max(x) => write!(f, "at most {}", x),
561 }
562 }
563}
564
565impl std::fmt::Display for InvalidParameterCount {
566 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
567 write!(f, "invalid parameter count, expected {}, got {}", self.expected, self.actual)
568 }
569}