use crate::state::InvalidState;
use core::fmt::Debug;

#[derive(Debug)]
pub enum RfError<SE: Debug> {
    InvalidState(InvalidState),
    SpiError(SE),
}

impl<SE: Debug> From<InvalidState> for RfError<SE> {
    fn from(is: InvalidState) -> Self {
        Self::InvalidState(is)
    }
}

#[derive(Debug)]
pub enum TransferError<SE: Debug> {
    // also handles underflows
    FifoOverflow,
    // Expected a packet of length N, however
    // the chip gave us >N bytes
    TooMuchData,
    SpiError(SE),
}

#[derive(Debug)]
pub enum TxError<SE: Debug> {
    // Given slice was bigger than the maximum packet size
    TooMuchData,
    SpiError(SE),
}

pub(crate) trait SpiErrorToOtherError<T, E: Debug> {
    fn re(self) -> Result<T, RfError<E>>
    where
        Self: Sized;

    fn te(self) -> Result<T, TransferError<E>>;

    fn txe(self) -> Result<T, TxError<E>>;
}

impl<T, E: Debug> SpiErrorToOtherError<T, E> for Result<T, E> {
    fn re(self) -> Result<T, RfError<E>> {
        self.map_err(|e| RfError::SpiError(e))
    }

    fn te(self) -> Result<T, TransferError<E>> {
        self.map_err(|e| TransferError::SpiError(e))
    }

    fn txe(self) -> Result<T, TxError<E>> {
        self.map_err(|e| TxError::SpiError(e))
    }
}