simx00x 0.1.0

A no-std and no-alloc driver for SIM800L GSM modules (and probably similar modules)
Documentation
use core::fmt::{Debug, Display};

use embedded_io::ErrorType;
use heapless::CapacityError;

use crate::state_machine::State;

/// Possible errors which can occur during module's life.
pub enum SimError<IO: ErrorType> {
    /// IO error, i.e. UART read/write error.
    IOError(IO::Error),
    /// String formatting error.
    FmtError(core::fmt::Error),
    /// String capacity exceeded error.
    StringCapacityError(CapacityError),
    /// SMS queue capacity exceeded error.
    SmsQueueLimitReached,
    /// The SIM is stalled.
    ModuleStalled,
    /// A PIN code is needed to unlock the SIM card.
    PinNeeded,
    /// An error occurred as a result of an AT command.
    AtError(State),
    /// The SIM is being powered down.
    PoweringDown,
    /// The SIM is powered down.
    PoweredDown,
}

impl<IO: ErrorType> Debug for SimError<IO> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        <Self as Display>::fmt(&self, f)
    }
}

impl<IO: ErrorType> Display for SimError<IO> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            SimError::IOError(e) => write!(f, "IO error: {e}"),
            SimError::FmtError(error) => write!(f, "String fmt error: {error}"),
            SimError::StringCapacityError(capacity_error) => write!(
                f,
                "An internal String has been used past its maximum capacity: {capacity_error}"
            ),
            SimError::SmsQueueLimitReached => {
                write!(f, "SMS queue limit reached. Try again later.")
            }
            SimError::ModuleStalled => write!(f, "The SIM is stalled."),
            SimError::PinNeeded => write!(f, "A PIN code is needed to unlock the SIM."),
            SimError::AtError(state) => {
                write!(f, "An AT command returned an error in state {:?}.", state)
            }
            SimError::PoweringDown => write!(
                f,
                "The SIM is being powered down; no commands can be accepted."
            ),
            SimError::PoweredDown => write!(
                f,
                "The SIM is powered down. To power it up again, set the DTR pin to high and call the module's `reset()` method."
            ),
        }
    }
}

impl<IO: ErrorType> From<core::fmt::Error> for SimError<IO> {
    fn from(value: core::fmt::Error) -> Self {
        SimError::FmtError(value)
    }
}

impl<IO: ErrorType> From<heapless::CapacityError> for SimError<IO> {
    fn from(value: heapless::CapacityError) -> Self {
        SimError::StringCapacityError(value)
    }
}