Skip to main content

device_envoy_rp/
error.rs

1#[cfg(not(feature = "host"))]
2use core::convert::Infallible;
3
4use derive_more::derive::{Display, Error};
5use device_envoy_core::lcd_text::LcdTextError;
6use device_envoy_core::wifi_auto::WifiAutoError;
7use esp_hal_mfrc522::consts::PCDErrorCode;
8
9/// A specialized `Result` where the error is this crate's `Error` type.
10pub type Result<T, E = Error> = core::result::Result<T, E>;
11
12/// Define a unified error type for this crate.
13#[expect(missing_docs, reason = "The variants are self-explanatory.")]
14#[derive(Debug, Display, Error)]
15pub enum Error {
16    // `#[error(not(source))]` below tells `derive_more` that `embassy_executor::SpawnError` does
17    // not implement Rust's `core::error::Error` trait.  `SpawnError` should, but Rust's `Error`
18    // only recently moved from `std` (which is not available in bare-metal development) to `core`
19    // (which is). Perhaps a future update of `embassy_executor::SpawnError` will implement
20    // `core::error::Error` which will make this unnecessary.
21    #[display("{_0:?}")]
22    TaskSpawn(#[error(not(source))] embassy_executor::SpawnError),
23
24    #[display("bits_to_indexes does not have enough preallocated space")]
25    BitsToIndexesNotEnoughSpace,
26
27    #[display("BitsToIndexes is full")]
28    BitsToIndexesFull,
29
30    #[display("Error setting output state")]
31    CannotSetOutputState,
32
33    #[display("Index out of bounds")]
34    IndexOutOfBounds,
35
36    #[display("MFRC522 initialization failed: {_0:?}")]
37    Mfrc522Init(#[error(not(source))] PCDErrorCode),
38
39    #[display("MFRC522 version read failed: {_0:?}")]
40    Mfrc522Version(#[error(not(source))] PCDErrorCode),
41
42    #[display("Format error")]
43    FormatError,
44
45    #[display("Character LCD operation failed: {_0:?}")]
46    LcdText(#[error(not(source))] LcdTextError),
47
48    #[display("Custom WiFi Auto field missing")]
49    MissingCustomWifiAutoField,
50
51    #[display("Network Time Protocol (NTP) error: {_0}")]
52    Ntp(#[error(not(source))] &'static str),
53
54    #[cfg(not(feature = "host"))]
55    #[display("Flash operation failed: {_0:?}")]
56    Flash(#[error(not(source))] embassy_rp::flash::Error),
57
58    #[display("Storage is invalid or corrupted")]
59    StorageCorrupted,
60}
61
62impl From<()> for Error {
63    fn from(_: ()) -> Self {
64        Self::FormatError
65    }
66}
67
68#[cfg(not(feature = "host"))]
69impl From<Infallible> for Error {
70    fn from(value: Infallible) -> Self {
71        match value {}
72    }
73}
74
75impl From<embassy_executor::SpawnError> for Error {
76    fn from(err: embassy_executor::SpawnError) -> Self {
77        Self::TaskSpawn(err)
78    }
79}
80
81impl From<device_envoy_core::led4::Led4BitsToIndexesError> for Error {
82    fn from(error: device_envoy_core::led4::Led4BitsToIndexesError) -> Self {
83        match error {
84            device_envoy_core::led4::Led4BitsToIndexesError::Full => Self::BitsToIndexesFull,
85        }
86    }
87}
88
89impl From<WifiAutoError> for Error {
90    fn from(error: WifiAutoError) -> Self {
91        match error {
92            WifiAutoError::FormatError => Self::FormatError,
93            WifiAutoError::StorageCorrupted => Self::StorageCorrupted,
94            WifiAutoError::MissingCustomWifiAutoField => Self::MissingCustomWifiAutoField,
95        }
96    }
97}
98
99impl From<LcdTextError> for Error {
100    fn from(error: LcdTextError) -> Self {
101        Self::LcdText(error)
102    }
103}