use std::fmt;
use rppal::gpio::{Gpio, InputPin};
pub const GPIO_TOUCH_A: u8 = 21;
pub const GPIO_TOUCH_B: u8 = 20;
pub const GPIO_TOUCH_C: u8 = 16;
#[derive(Debug)]
pub struct Button {
bcm_pin: u8,
pin: Option<Box<InputPin>>,
state: bool,
simulation: bool,
is_setup: bool,
}
impl Button {
pub fn new(bcm_pin: u8) -> Result<Button, Error> {
Ok(Self {
bcm_pin,
pin: None,
state: false,
simulation: false,
is_setup: false,
})
}
pub fn setup(&mut self) -> Result <(), Error> {
if !self.is_setup {
if !self.simulation {
let gpio = Gpio::new()?;
let input = gpio.get(self.bcm_pin)?.into_input();
self.pin = Some(Box::new(input));
}
self.is_setup = true;
}
Ok(())
}
pub fn is_pressed(&mut self) -> bool {
if !self.is_setup {
let _result = self.setup();
}
if !self.simulation {
let pin = self.pin.as_deref_mut().unwrap();
self.state = !pin.is_high();
}
self.state
}
}
pub struct Buttons {
pub a : Button,
pub b: Button,
pub c: Button,
}
impl Buttons {
pub fn new() -> Result<Buttons, Error> {
Ok(Self {
a: Button::new(GPIO_TOUCH_A)?,
b: Button::new(GPIO_TOUCH_B)?,
c: Button::new(GPIO_TOUCH_C)?,
})
}
pub fn enable_simulation(&mut self) {
self.a.simulation = true;
self.b.simulation = true;
self.c.simulation = true;
}
}
#[derive(Debug)]
pub enum Error {
Gpio(rppal::gpio::Error),
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &*self {
Error::Gpio(err) => write!(f, "Gpio error: {}", &err),
}
}
}
impl From<rppal::gpio::Error> for Error {
fn from(err: rppal::gpio::Error) -> Error {
Error::Gpio(err)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_button_setup() -> Result<(), Error> {
let mut button = Button::new(GPIO_TOUCH_A)?;
button.simulation = true;
assert!(button.is_setup == false);
let _result = button.setup();
assert!(button.is_setup == true);
Ok(())
}
#[test]
fn test_button_is_pressed() -> Result<(), Error> {
let mut button = Button::new(GPIO_TOUCH_A)?;
button.simulation = true;
assert!(button.is_setup == false);
assert!(button.is_pressed() == false);
assert!(button.is_setup == true);
button.state = true;
assert!(button.is_pressed() == true);
Ok(())
}
#[test]
fn test_buttons_new() -> Result<(), Error> {
let buttons = Buttons::new()?;
assert!(buttons.a.bcm_pin == 21);
assert!(buttons.b.bcm_pin == 20);
assert!(buttons.c.bcm_pin == 16);
Ok(())
}
#[test]
fn test_buttons_enable_simulation() -> Result<(), Error> {
let mut buttons = Buttons::new()?;
assert!(!buttons.a.simulation);
assert!(!buttons.b.simulation);
assert!(!buttons.c.simulation);
buttons.enable_simulation();
assert!(buttons.a.simulation);
assert!(buttons.b.simulation);
assert!(buttons.c.simulation);
Ok(())
}
}