ftdi_embedded_hal/
error.rs

1use eh1::i2c::NoAcknowledgeSource;
2use std::{fmt, io};
3
4/// Error type.
5#[derive(Debug)]
6pub enum Error<E: std::error::Error> {
7    /// ftdi-embedded-hal implementation specific error.
8    Hal(ErrorKind),
9    /// IO error.
10    Io(io::Error),
11    /// Backend specific error.
12    Backend(E),
13}
14
15/// Internal HAL errors
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17#[non_exhaustive]
18pub enum ErrorKind {
19    /// No ACK from the I2C slave
20    I2cNoAck(NoAcknowledgeSource),
21}
22
23impl ErrorKind {
24    fn as_str(&self) -> &str {
25        match *self {
26            ErrorKind::I2cNoAck(NoAcknowledgeSource::Address) => {
27                "No ACK from slave during addressing"
28            }
29            ErrorKind::I2cNoAck(NoAcknowledgeSource::Data) => {
30                "No ACK from slave during data transfer"
31            }
32            ErrorKind::I2cNoAck(NoAcknowledgeSource::Unknown) => "No ACK from slave",
33        }
34    }
35}
36
37impl<E: std::error::Error> eh1::i2c::Error for Error<E> {
38    fn kind(&self) -> eh1::i2c::ErrorKind {
39        match self {
40            Self::Hal(ErrorKind::I2cNoAck(src)) => eh1::i2c::ErrorKind::NoAcknowledge(*src),
41            _ => eh1::i2c::ErrorKind::Other,
42        }
43    }
44}
45
46impl<E: std::error::Error> eh1::digital::Error for Error<E> {
47    fn kind(&self) -> eh1::digital::ErrorKind {
48        eh1::digital::ErrorKind::Other
49    }
50}
51
52impl<E: std::error::Error> fmt::Display for Error<E> {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        match self {
55            Error::Io(e) => e.fmt(f),
56            Error::Backend(e) => fmt::Display::fmt(&e, f),
57            Error::Hal(e) => write!(f, "A regular error occurred {:?}", e.as_str()),
58        }
59    }
60}
61
62impl<E: std::error::Error> std::error::Error for Error<E> {
63    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
64        match self {
65            Error::Io(e) => e.source(),
66            Error::Backend(e) => e.source(),
67            Error::Hal(_) => None,
68        }
69    }
70}
71
72impl<E: std::error::Error> From<io::Error> for Error<E> {
73    fn from(e: io::Error) -> Self {
74        Error::Io(e)
75    }
76}
77
78#[cfg(feature = "ftdi")]
79impl From<ftdi::Error> for Error<ftdi::Error> {
80    fn from(e: ftdi::Error) -> Self {
81        Error::Backend(e)
82    }
83}
84
85#[cfg(feature = "libftd2xx")]
86impl From<libftd2xx::TimeoutError> for Error<libftd2xx::TimeoutError> {
87    fn from(e: libftd2xx::TimeoutError) -> Self {
88        Error::Backend(e)
89    }
90}