use std::io;
use derive_more::Display;
use rppal::gpio;
use rppal::uart;
#[derive(Display, Debug)]
pub enum Error {
#[display(fmt = "Maestro struct is uninitialized.")]
Uninitialized,
#[display(
fmt = "Target must be between 3968 quarter-us (992us) and 8000 quarter-us (2000us) but {} quarter-us was used.",
_0
)]
InvalidValue(u16),
#[display(
fmt = "2 bytes were expected to be read but only {} byte(s) were actually read.",
actual_count
)]
FaultyRead {
actual_count: usize,
},
#[display(
fmt = "{} bytes were expected to be written, but only {} byte(s) were actually written.",
actual_count,
expected_count
)]
FaultyWrite {
actual_count: usize,
expected_count: usize,
},
#[display(fmt = "{}", _0)]
Io(io::Error),
}
#[doc(hidden)]
impl Error {
fn new_io_error<E>(err_kind: io::ErrorKind, err_msg: E) -> Self
where
E: Into<Box<dyn std::error::Error + Send + Sync>>,
{
Self::Io(io::Error::new(err_kind, err_msg))
}
}
impl std::error::Error for Error {}
impl From<uart::Error> for Error {
fn from(uart_error: uart::Error) -> Self {
match uart_error {
uart::Error::Io(err) => Self::Io(err),
uart::Error::Gpio(gpio_err) => match gpio_err {
gpio::Error::UnknownModel => {
Self::new_io_error(io::ErrorKind::Other, "Unknown model.")
},
gpio::Error::PinNotAvailable(pin) => Self::new_io_error(
io::ErrorKind::AddrNotAvailable,
format!("Pin number {} is not available.", pin),
),
gpio::Error::PermissionDenied(err_string) => {
Self::new_io_error(
io::ErrorKind::PermissionDenied,
format!("Permission denied: {}.", err_string),
)
},
gpio::Error::Io(err) => Self::Io(err),
gpio::Error::ThreadPanic => {
Self::new_io_error(io::ErrorKind::Other, "Thread panic.")
},
gpio::Error::PinUsed(_) => Self::new_io_error(io::ErrorKind::AddrInUse, "That pin is already being used."),
},
uart::Error::InvalidValue => {
Self::new_io_error(io::ErrorKind::Other, "Invalid value.")
},
}
}
}