1use rtc_hal::datetime::DateTimeError;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11pub enum Error<I2cError>
12where
13 I2cError: core::fmt::Debug,
14{
15 I2c(I2cError),
17 InvalidAddress,
19 UnsupportedSqwFrequency,
21 DateTime(DateTimeError),
23 InvalidBaseCentury,
25}
26
27impl<I2cError> core::fmt::Display for Error<I2cError>
28where
29 I2cError: core::fmt::Debug + core::fmt::Display,
30{
31 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32 match self {
33 Error::I2c(e) => write!(f, "I2C communication error: {e}"),
34 Error::InvalidAddress => write!(f, "Invalid register address"),
35 Error::DateTime(e) => write!(f, "Invalid date/time values: {e}"),
36 Error::UnsupportedSqwFrequency => write!(f, "Unsupported square wave frequency"),
37 Error::InvalidBaseCentury => write!(f, "Base century must be 19 or greater"),
38 }
39 }
40}
41
42impl<I2cError> core::error::Error for Error<I2cError> where
43 I2cError: core::fmt::Debug + core::fmt::Display
44{
45}
46
47impl<I2cError> From<I2cError> for Error<I2cError>
51where
52 I2cError: core::fmt::Debug,
53{
54 fn from(value: I2cError) -> Self {
55 Error::I2c(value)
56 }
57}
58
59impl<I2cError> rtc_hal::error::Error for Error<I2cError>
60where
61 I2cError: core::fmt::Debug,
62{
63 fn kind(&self) -> rtc_hal::error::ErrorKind {
64 match self {
65 Error::I2c(_) => rtc_hal::error::ErrorKind::Bus,
66 Error::InvalidAddress => rtc_hal::error::ErrorKind::InvalidAddress,
67 Error::DateTime(_) => rtc_hal::error::ErrorKind::InvalidDateTime,
68 Error::UnsupportedSqwFrequency => rtc_hal::error::ErrorKind::UnsupportedSqwFrequency,
69 Error::InvalidBaseCentury => rtc_hal::error::ErrorKind::InvalidDateTime,
70 }
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use rtc_hal::datetime::DateTimeError;
78 use rtc_hal::error::{Error as RtcError, ErrorKind};
79
80 #[test]
81 fn test_from_i2c_error() {
82 #[derive(Debug, PartialEq, Eq)]
83 struct DummyI2cError(u8);
84
85 let e = Error::from(DummyI2cError(42));
86 assert_eq!(e, Error::I2c(DummyI2cError(42)));
87 }
88
89 #[test]
90 fn test_error_kind_mappings() {
91 let e: Error<&str> = Error::I2c("oops");
93 assert_eq!(e.kind(), ErrorKind::Bus);
94
95 let e: Error<&str> = Error::InvalidAddress;
97 assert_eq!(e.kind(), ErrorKind::InvalidAddress);
98
99 let e: Error<&str> = Error::DateTime(DateTimeError::InvalidDay);
101 assert_eq!(e.kind(), ErrorKind::InvalidDateTime);
102
103 let e: Error<&str> = Error::UnsupportedSqwFrequency;
105 assert_eq!(e.kind(), ErrorKind::UnsupportedSqwFrequency);
106
107 let e: Error<&str> = Error::InvalidBaseCentury;
109 assert_eq!(e.kind(), ErrorKind::InvalidDateTime);
110 }
111
112 #[derive(Debug, PartialEq, Eq)]
113 struct MockI2cError {
114 code: u8,
115 message: &'static str,
116 }
117
118 impl core::fmt::Display for MockI2cError {
119 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
120 write!(f, "I2C Error {}: {}", self.code, self.message)
121 }
122 }
123
124 #[test]
125 fn test_display_all_variants() {
126 let errors = vec![
127 (
128 Error::I2c(MockI2cError {
129 code: 1,
130 message: "test",
131 }),
132 "I2C communication error: I2C Error 1: test",
133 ),
134 (Error::InvalidAddress, "Invalid register address"),
135 (
136 Error::DateTime(DateTimeError::InvalidMonth),
137 "Invalid date/time values: invalid month",
138 ),
139 (
140 Error::UnsupportedSqwFrequency,
141 "Unsupported square wave frequency",
142 ),
143 (
144 Error::InvalidBaseCentury,
145 "Base century must be 19 or greater",
146 ),
147 ];
148
149 for (error, expected) in errors {
150 assert_eq!(format!("{error}"), expected);
151 }
152 }
153}