embedded_hal_fuzz/
pwm.rs

1//! To make use of this module you can simply pass
2//! this in as a value from the fuzz_target macro e.g.
3//!
4//! # Example
5//!
6//! ```rust
7//! use libfuzzer_sys::fuzz_target;
8//! use embedded_hal_fuzz::pwm::ArbitraryPwm;
9//! use embedded_hal::pwm::SetDutyCycle;
10//!
11//! fuzz_target!(|pwm: ArbitraryPwm| {
12//!   let mut pwm = pwm;
13//!   let _ = pwm.set_duty_cycle(10);
14//! });
15//! ```
16
17use arbitrary::Arbitrary;
18use embedded_hal::pwm::{self, ErrorKind, ErrorType, SetDutyCycle};
19
20#[derive(Debug)]
21pub struct Error {
22    kind: ErrorKind,
23}
24
25impl pwm::Error for Error {
26    fn kind(&self) -> ErrorKind {
27        self.kind
28    }
29}
30
31impl<'a> Arbitrary<'a> for Error {
32    fn arbitrary(_: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
33        Ok(Error {
34            kind: ErrorKind::Other,
35        })
36    }
37}
38
39/// Creates a fuzzed Pwm driver, this type is intended to be constructed
40/// the arbitrary crate e.g.
41/// ```rust
42/// use arbitrary::{Arbitrary, Unstructured};
43/// use embedded_hal_fuzz::pwm::ArbitraryPwm;
44/// let raw_fuzzed_data = &[1u8, 2, 3, 4, 5][..];
45/// let mut unstructured = Unstructured::new(raw_fuzzed_data);
46/// let spi_bus = ArbitraryPwm::arbitrary(&mut unstructured);
47/// ```
48#[derive(Debug, Arbitrary)]
49pub struct ArbitraryPwm {
50    max_duty_cycle: u16,
51    maybe_error: Vec<Result<(), Error>>,
52}
53
54impl ErrorType for ArbitraryPwm {
55    type Error = Error;
56}
57
58impl SetDutyCycle for ArbitraryPwm {
59    fn max_duty_cycle(&self) -> u16 {
60        self.max_duty_cycle
61    }
62
63    fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
64        if duty > self.max_duty_cycle {
65            return Err(Error {
66                kind: ErrorKind::Other,
67            });
68        }
69        if let Some(result) = self.maybe_error.pop() {
70            return result;
71        }
72        Ok(())
73    }
74}