use thiserror::Error;
#[derive(Error, Debug)]
pub enum ProtocolError {
#[error(transparent)]
UTF(#[from] core::str::Utf8Error),
#[error(transparent)]
Scan(#[from] scan_fmt::parse::ScanError),
#[error("Unparsable response: {0:?}")]
Parse(Vec<u8>),
}
#[derive(Error, Debug)]
pub enum Error {
#[error("No ACK received for address")]
MissingAddrAck,
#[error("No ACK received for data")]
MissingDataAck,
#[error("I2C bus arbitration lost")]
Arbitration,
#[error("Timeout waiting for response")]
Timeout,
#[error("Could not open {path}: {source}")]
Open {
path: String,
source: serialport::Error,
},
#[error("Invalid Address: {0}")]
Address(u8),
#[error("Communication Failure: {0}")]
Transport(#[source] std::io::Error),
#[error("Could not parse response: {0}")]
Protocol(#[from] ProtocolError),
}
impl From<std::io::Error> for Error {
fn from(item: std::io::Error) -> Self {
match item.kind() {
std::io::ErrorKind::TimedOut => Error::Timeout,
_ => Error::Transport(item),
}
}
}
#[cfg(feature = "eh1")]
impl embedded_hal_1::i2c::Error for Error {
fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
use embedded_hal_1::i2c::ErrorKind;
match self {
Self::Arbitration => ErrorKind::ArbitrationLoss,
Self::MissingAddrAck => {
ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
}
Self::MissingDataAck => {
ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Data)
}
_ => ErrorKind::Other,
}
}
}