use alloc::format; use alloc::string::{String, ToString}; use core::convert::Infallible; use core::fmt; use core::str::Utf8Error; use embassy_embedded_hal::shared_bus::I2cDeviceError; use embassy_executor::SpawnError; use embassy_sync::mutex::TryLockError; use embedded_storage::nor_flash::NorFlashErrorKind; use esp_hal::i2c::master::ConfigError; use esp_hal::pcnt::unit::{InvalidHighLimit, InvalidLowLimit}; use esp_hal::twai::EspTwaiError; use esp_wifi::wifi::WifiError; use ina219::errors::{BusVoltageReadError, ShuntVoltageReadError}; use littlefs2_core::PathError; use onewire::Error; use pca9535::ExpanderError; //All error superconstruct #[derive(Debug)] pub enum FatError { OneWireError { error: Error, }, String { error: String, }, LittleFSError { error: littlefs2_core::Error, }, PathError { error: PathError, }, TryLockError { error: TryLockError, }, WifiError { error: WifiError, }, SerdeError { error: serde_json::Error, }, PreconditionFailed { error: String, }, NoBatteryMonitor, SpawnError { error: SpawnError, }, PartitionError { error: esp_bootloader_esp_idf::partitions::Error, }, I2CConfigError { error: ConfigError, }, DS323 { error: String, }, Eeprom24x { error: String, }, ExpanderError { error: String, }, CanBusError { error: EspTwaiError, }, SNTPError { error: sntpc::Error, }, } pub type FatResult = Result; impl fmt::Display for FatError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { FatError::SpawnError { error } => { write!(f, "SpawnError {:?}", error.to_string()) } FatError::OneWireError { error } => write!(f, "OneWireError {:?}", error), FatError::String { error } => write!(f, "{}", error), FatError::LittleFSError { error } => write!(f, "LittleFSError {:?}", error), FatError::PathError { error } => write!(f, "PathError {:?}", error), FatError::TryLockError { error } => write!(f, "TryLockError {:?}", error), FatError::WifiError { error } => write!(f, "WifiError {:?}", error), FatError::SerdeError { error } => write!(f, "SerdeError {:?}", error), FatError::PreconditionFailed { error } => write!(f, "PreconditionFailed {:?}", error), FatError::PartitionError { error } => { write!(f, "PartitionError {:?}", error) } FatError::NoBatteryMonitor => { write!(f, "No Battery Monitor") } FatError::I2CConfigError { error } => write!(f, "I2CConfigError {:?}", error), FatError::DS323 { error } => write!(f, "DS323 {:?}", error), FatError::Eeprom24x { error } => write!(f, "Eeprom24x {:?}", error), FatError::ExpanderError { error } => write!(f, "ExpanderError {:?}", error), FatError::CanBusError { error } => { write!(f, "CanBusError {:?}", error) } FatError::SNTPError { error } => write!(f, "SNTPError {:?}", error), } } } #[macro_export] macro_rules! bail { ($msg:literal $(,)?) => { return $crate::fat_error::fat_bail($msg) }; ($fmt:literal, $($arg:tt)*) => { return $crate::fat_error::fat_bail(&alloc::format!($fmt, $($arg)*)) }; } pub fn fat_bail(message: &str) -> Result { Err(FatError::String { error: message.to_string(), }) } pub trait ContextExt { fn context(self, context: C) -> Result where C: AsRef; } impl ContextExt for Option { fn context(self, context: C) -> Result where C: AsRef, { match self { Some(value) => Ok(value), None => Err(FatError::PreconditionFailed { error: context.as_ref().to_string(), }), } } } impl From> for FatError { fn from(error: Error) -> Self { FatError::OneWireError { error } } } impl From for FatError { fn from(value: littlefs2_core::Error) -> Self { FatError::LittleFSError { error: value } } } impl From for FatError { fn from(value: PathError) -> Self { FatError::PathError { error: value } } } impl From for FatError { fn from(value: TryLockError) -> Self { FatError::TryLockError { error: value } } } impl From for FatError { fn from(value: WifiError) -> Self { FatError::WifiError { error: value } } } impl From for FatError { fn from(value: serde_json::Error) -> Self { FatError::SerdeError { error: value } } } impl From for FatError { fn from(value: SpawnError) -> Self { FatError::SpawnError { error: value } } } impl From for FatError { fn from(value: esp_bootloader_esp_idf::partitions::Error) -> Self { FatError::PartitionError { error: value } } } impl From for FatError { fn from(value: Utf8Error) -> Self { FatError::String { error: value.to_string(), } } } impl From> for FatError { fn from(value: edge_http::io::Error) -> Self { FatError::String { error: format!("{:?}", value), } } } impl From> for FatError { fn from(value: ds323x::Error) -> Self { FatError::DS323 { error: format!("{:?}", value), } } } impl From> for FatError { fn from(value: eeprom24x::Error) -> Self { FatError::Eeprom24x { error: format!("{:?}", value), } } } impl From>> for FatError { fn from(value: ExpanderError>) -> Self { FatError::ExpanderError { error: format!("{:?}", value), } } } impl From for FatError { fn from(value: bincode::error::DecodeError) -> Self { FatError::Eeprom24x { error: format!("{:?}", value), } } } impl From for FatError { fn from(value: bincode::error::EncodeError) -> Self { FatError::Eeprom24x { error: format!("{:?}", value), } } } impl From for FatError { fn from(value: ConfigError) -> Self { FatError::I2CConfigError { error: value } } } impl From> for FatError { fn from(value: I2cDeviceError) -> Self { FatError::String { error: format!("{:?}", value), } } } impl From>> for FatError { fn from(value: BusVoltageReadError>) -> Self { FatError::String { error: format!("{:?}", value), } } } impl From>> for FatError { fn from(value: ShuntVoltageReadError>) -> Self { FatError::String { error: format!("{:?}", value), } } } impl From for FatError { fn from(value: Infallible) -> Self { panic!("Infallible error: {:?}", value) } } impl From for FatError { fn from(value: InvalidLowLimit) -> Self { FatError::String { error: format!("{:?}", value), } } } impl From for FatError { fn from(value: InvalidHighLimit) -> Self { FatError::String { error: format!("{:?}", value), } } } impl From> for FatError { fn from(value: nb::Error) -> Self { match value { nb::Error::Other(can_error) => FatError::CanBusError { error: can_error }, nb::Error::WouldBlock => FatError::String { error: "Would block".to_string(), }, } } } impl From for FatError { fn from(value: NorFlashErrorKind) -> Self { FatError::String { error: value.to_string(), } } } impl From for FatError { fn from(value: sntpc::Error) -> Self { FatError::SNTPError { error: value } } }