1use core::{convert::From, ops::Not};
4
5#[cfg(feature = "defmt-03")]
6use crate::defmt;
7
8pub trait Error: core::fmt::Debug {
10    fn kind(&self) -> ErrorKind;
16}
17
18impl Error for core::convert::Infallible {
19    fn kind(&self) -> ErrorKind {
20        match *self {}
21    }
22}
23
24#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
30#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
31#[non_exhaustive]
32pub enum ErrorKind {
33    Other,
35}
36
37impl Error for ErrorKind {
38    #[inline]
39    fn kind(&self) -> ErrorKind {
40        *self
41    }
42}
43
44impl core::fmt::Display for ErrorKind {
45    #[inline]
46    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47        match self {
48            Self::Other => write!(
49                f,
50                "A different error occurred. The original error may contain more information"
51            ),
52        }
53    }
54}
55
56pub trait ErrorType {
60    type Error: Error;
62}
63
64impl<T: ErrorType + ?Sized> ErrorType for &T {
65    type Error = T::Error;
66}
67
68impl<T: ErrorType + ?Sized> ErrorType for &mut T {
69    type Error = T::Error;
70}
71
72#[derive(Debug, PartialEq, Eq, Clone, Copy)]
83#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
84pub enum PinState {
85    Low,
87    High,
89}
90
91impl From<bool> for PinState {
92    #[inline]
93    fn from(value: bool) -> Self {
94        match value {
95            false => PinState::Low,
96            true => PinState::High,
97        }
98    }
99}
100
101impl Not for PinState {
102    type Output = PinState;
103
104    #[inline]
105    fn not(self) -> Self::Output {
106        match self {
107            PinState::High => PinState::Low,
108            PinState::Low => PinState::High,
109        }
110    }
111}
112
113impl From<PinState> for bool {
114    #[inline]
115    fn from(value: PinState) -> bool {
116        match value {
117            PinState::Low => false,
118            PinState::High => true,
119        }
120    }
121}
122
123pub trait OutputPin: ErrorType {
125    fn set_low(&mut self) -> Result<(), Self::Error>;
130
131    fn set_high(&mut self) -> Result<(), Self::Error>;
136
137    #[inline]
142    fn set_state(&mut self, state: PinState) -> Result<(), Self::Error> {
143        match state {
144            PinState::Low => self.set_low(),
145            PinState::High => self.set_high(),
146        }
147    }
148}
149
150impl<T: OutputPin + ?Sized> OutputPin for &mut T {
151    #[inline]
152    fn set_low(&mut self) -> Result<(), Self::Error> {
153        T::set_low(self)
154    }
155
156    #[inline]
157    fn set_high(&mut self) -> Result<(), Self::Error> {
158        T::set_high(self)
159    }
160
161    #[inline]
162    fn set_state(&mut self, state: PinState) -> Result<(), Self::Error> {
163        T::set_state(self, state)
164    }
165}
166
167pub trait StatefulOutputPin: OutputPin {
169    fn is_set_high(&mut self) -> Result<bool, Self::Error>;
173
174    fn is_set_low(&mut self) -> Result<bool, Self::Error>;
178
179    fn toggle(&mut self) -> Result<(), Self::Error> {
181        let was_low: bool = self.is_set_low()?;
182        self.set_state(PinState::from(was_low))
183    }
184}
185
186impl<T: StatefulOutputPin + ?Sized> StatefulOutputPin for &mut T {
187    #[inline]
188    fn is_set_high(&mut self) -> Result<bool, Self::Error> {
189        T::is_set_high(self)
190    }
191
192    #[inline]
193    fn is_set_low(&mut self) -> Result<bool, Self::Error> {
194        T::is_set_low(self)
195    }
196
197    #[inline]
198    fn toggle(&mut self) -> Result<(), Self::Error> {
199        T::toggle(self)
200    }
201}
202
203pub trait InputPin: ErrorType {
205    fn is_high(&mut self) -> Result<bool, Self::Error>;
207
208    fn is_low(&mut self) -> Result<bool, Self::Error>;
210}
211
212impl<T: InputPin + ?Sized> InputPin for &mut T {
213    #[inline]
214    fn is_high(&mut self) -> Result<bool, Self::Error> {
215        T::is_high(self)
216    }
217
218    #[inline]
219    fn is_low(&mut self) -> Result<bool, Self::Error> {
220        T::is_low(self)
221    }
222}