use core::{convert::From, ops::Not};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum PinState {
Low,
High,
}
impl From<bool> for PinState {
fn from(value: bool) -> Self {
match value {
false => PinState::Low,
true => PinState::High,
}
}
}
impl Not for PinState {
type Output = PinState;
fn not(self) -> Self::Output {
match self {
PinState::High => PinState::Low,
PinState::Low => PinState::High,
}
}
}
pub trait OutputPin {
type Error;
fn try_set_low(&mut self) -> Result<(), Self::Error>;
fn try_set_high(&mut self) -> Result<(), Self::Error>;
fn try_set_state(&mut self, state: PinState) -> Result<(), Self::Error> {
match state {
PinState::Low => self.try_set_low(),
PinState::High => self.try_set_high(),
}
}
}
pub trait StatefulOutputPin: OutputPin {
fn try_is_set_high(&self) -> Result<bool, Self::Error>;
fn try_is_set_low(&self) -> Result<bool, Self::Error>;
}
pub trait ToggleableOutputPin {
type Error;
fn try_toggle(&mut self) -> Result<(), Self::Error>;
}
pub mod toggleable {
use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
pub trait Default: OutputPin + StatefulOutputPin {}
impl<P> ToggleableOutputPin for P
where
P: Default,
{
type Error = P::Error;
fn try_toggle(&mut self) -> Result<(), Self::Error> {
if self.try_is_set_low()? {
self.try_set_high()
} else {
self.try_set_low()
}
}
}
}
pub trait InputPin {
type Error;
fn try_is_high(&self) -> Result<bool, Self::Error>;
fn try_is_low(&self) -> Result<bool, Self::Error>;
}