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) {
64 self.pin.press();
65 self.tick();
66 assert!(matches!(self.state, State::Down(_)));
67
68 sleep(CONFIG.debounce);
69 self.tick();
70 }
71
72 pub fn release_button(&mut self) {
74 self.pin.release();
75 self.tick();
76 }
77
78 pub fn hold_button(&mut self) {
80 self.press_button();
81 sleep(CONFIG.hold);
82 self.tick();
83 self.release_button();
84 }
85 }
86
87 impl MockPin {
88 pub fn press(&self) {
90 self.0.store(true, Ordering::SeqCst);
91 sleep(CONFIG.debounce);
92 }
93
94 pub fn release(&self) {
96 self.0.store(false, Ordering::SeqCst);
97 sleep(CONFIG.debounce);
98 }
99
100 pub fn click(&self) {
102 self.press();
103 self.release();
104 }
105
106 pub fn hold(&self) {
108 self.press();
109 sleep(CONFIG.hold);
110 self.release();
111 }
112 }
113}