button_driver/
pin_wrapper.rs1pub trait PinWrapper {
3 fn is_high(&mut self) -> bool;
5
6 fn is_low(&mut self) -> bool {
8 !self.is_high()
9 }
10}
11
12#[cfg(feature = "embedded_hal_old")]
13impl<P> PinWrapper for P
14where
15 Self: embedded_hal_old::digital::v2::InputPin,
16{
17 fn is_high(&mut self) -> bool {
18 embedded_hal_old::digital::v2::InputPin::is_high(self).unwrap_or_default()
19 }
20}
21
22#[cfg(feature = "embedded_hal")]
23impl<P> PinWrapper for P
24where
25 Self: embedded_hal::digital::InputPin,
26{
27 fn is_high(&mut self) -> bool {
28 embedded_hal::digital::InputPin::is_high(self).unwrap_or_default()
29 }
30}
31
32#[cfg(all(test, feature = "std"))]
33pub(crate) mod tests {
34 use std::{
35 sync::{
36 atomic::{AtomicBool, Ordering},
37 Arc,
38 },
39 thread::sleep,
40 time::{Duration, Instant},
41 };
42
43 use crate::{Button, ButtonConfig, Mode, PinWrapper, State};
44
45 pub const CONFIG: ButtonConfig = ButtonConfig {
46 hold: Duration::from_millis(500),
47 debounce: Duration::from_micros(700),
48 release: Duration::from_millis(30),
49 mode: Mode::PullDown,
50 };
51
52 #[derive(Debug, Default, Clone)]
53 pub struct MockPin(Arc<AtomicBool>);
54
55 impl PinWrapper for MockPin {
56 fn is_high(&mut self) -> bool {
57 self.0.load(Ordering::SeqCst)
58 }
59 }
60
61 impl Button<MockPin, Instant> {
62 pub fn press_button(&mut self) {
63 self.pin.press();
64 self.tick();
65 assert!(matches!(self.state, State::Down(_)));
66
67 sleep(CONFIG.debounce);
68 self.tick();
69 }
70
71 pub fn release_button(&mut self) {
72 self.pin.release();
73 self.tick();
74 }
75
76 pub fn hold_button(&mut self) {
77 self.press_button();
78 sleep(CONFIG.hold);
79 self.tick();
80 self.release_button();
81 }
82 }
83
84 impl MockPin {
85 pub fn press(&self) {
87 self.0.store(true, Ordering::SeqCst);
88 sleep(CONFIG.debounce);
89 }
90
91 pub fn release(&self) {
93 self.0.store(false, Ordering::SeqCst);
94 sleep(CONFIG.debounce);
95 }
96
97 pub fn click(&self) {
99 self.press();
100 self.release();
101 }
102
103 pub fn hold(&self) {
105 self.press();
106 sleep(CONFIG.hold);
107 self.release();
108 }
109 }
110}