use std::fmt;
use std::sync::{Mutex, PoisonError};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
NoBoard,
NotBegun(&'static str),
Core(rusty_esp_core::error::Error),
Io(String),
Missing(&'static str),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::NoBoard => f.write_str("no board installed: call board::install first"),
Error::NotBegun(what) => write!(f, "{what}: begin was not called"),
Error::Core(e) => write!(f, "{e:?}"),
Error::Io(e) => f.write_str(e),
Error::Missing(what) => write!(f, "the board has no {what}"),
}
}
}
impl std::error::Error for Error {}
impl From<rusty_esp_core::error::Error> for Error {
fn from(e: rusty_esp_core::error::Error) -> Self {
Error::Core(e)
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Error::Io(e.to_string())
}
}
pub type Result<T> = std::result::Result<T, Error>;
static LAST: Mutex<Option<Error>> = Mutex::new(None);
pub fn last_error() -> Option<Error> {
LAST.lock().unwrap_or_else(PoisonError::into_inner).clone()
}
pub(crate) fn record(e: Error) {
*LAST.lock().unwrap_or_else(PoisonError::into_inner) = Some(e);
}
pub(crate) fn clear() {
*LAST.lock().unwrap_or_else(PoisonError::into_inner) = None;
}
pub(crate) fn ok(r: Result<()>) -> bool {
match r {
Ok(()) => {
clear();
true
}
Err(e) => {
record(e);
false
}
}
}
pub(crate) fn some<T>(r: Result<Option<T>>) -> Option<T> {
match r {
Ok(v) => {
clear();
v
}
Err(e) => {
record(e);
None
}
}
}