embedded_hal_fuzz/
digital.rs1use std::cell::RefCell;
19
20use arbitrary::{Arbitrary, Unstructured};
21use embedded_hal::digital::{
22 self, ErrorKind, ErrorType, InputPin, OutputPin, PinState, StatefulOutputPin,
23};
24
25#[derive(Debug, Arbitrary)]
26pub struct Error;
27
28impl digital::Error for Error {
29 fn kind(&self) -> ErrorKind {
30 ErrorKind::Other
31 }
32}
33
34#[derive(Debug, Arbitrary)]
44pub struct ArbitraryInputPin {
45 pin_states: RefCell<Vec<Result<bool, Error>>>,
46}
47
48impl ErrorType for ArbitraryInputPin {
49 type Error = Error;
50}
51
52impl InputPin for ArbitraryInputPin {
53 fn is_high(&mut self) -> Result<bool, Self::Error> {
54 match self.pin_states.try_borrow_mut() {
55 Ok(mut pin_states) => match pin_states.pop() {
56 Some(result) => result,
57 None => Err(Error),
58 },
59 Err(_) => Err(Error),
60 }
61 }
62 fn is_low(&mut self) -> Result<bool, Self::Error> {
63 self.is_high().map(|x| !x)
64 }
65}
66
67#[derive(Debug, Arbitrary)]
77pub struct ArbitraryOutputPin {
78 maybe_error: RefCell<Vec<Option<Error>>>,
79 #[arbitrary(with = |u: &mut Unstructured| Ok(if bool::arbitrary(u)? {PinState::High} else {PinState::Low}))]
80 state: PinState,
81}
82
83impl OutputPin for ArbitraryOutputPin {
84 fn set_low(&mut self) -> Result<(), Self::Error> {
85 match self.maybe_error.try_borrow_mut().map_err(|_| Error)?.pop() {
86 Some(Some(error)) => Err(error),
87 _ => {
88 self.state = PinState::Low;
89 Ok(())
90 }
91 }
92 }
93 fn set_high(&mut self) -> Result<(), Self::Error> {
94 match self.maybe_error.try_borrow_mut().map_err(|_| Error)?.pop() {
95 Some(Some(error)) => Err(error),
96 _ => {
97 self.state = PinState::High;
98 Ok(())
99 }
100 }
101 }
102}
103
104impl StatefulOutputPin for ArbitraryOutputPin {
105 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
106 match self.maybe_error.try_borrow_mut().map_err(|_| Error)?.pop() {
107 Some(Some(error)) => Err(error),
108 _ => Ok(self.state == PinState::High),
109 }
110 }
111
112 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
113 match self.maybe_error.try_borrow_mut().map_err(|_| Error)?.pop() {
114 Some(Some(error)) => Err(error),
115 _ => Ok(self.state == PinState::Low),
116 }
117 }
118}
119
120impl ErrorType for ArbitraryOutputPin {
121 type Error = Error;
122}