1use arbitrary::Arbitrary;
19use embedded_hal::i2c::{
20 self, ErrorKind, I2c, NoAcknowledgeSource, Operation, SevenBitAddress, TenBitAddress,
21};
22use std::marker::PhantomData;
23
24#[derive(Debug)]
25pub struct Error {
26 kind: ErrorKind,
27}
28
29impl Default for Error {
30 fn default() -> Self {
31 Error {
32 kind: ErrorKind::Other,
33 }
34 }
35}
36
37impl i2c::Error for Error {
38 fn kind(&self) -> ErrorKind {
39 self.kind
40 }
41}
42
43impl<'a> Arbitrary<'a> for Error {
44 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
45 use ErrorKind::*;
46 use NoAcknowledgeSource::*;
47 Ok(Error {
48 kind: *u.choose(&[
49 Bus,
50 ArbitrationLoss,
51 NoAcknowledge(Address),
52 NoAcknowledge(Data),
53 NoAcknowledge(Unknown),
54 Overrun,
55 Other,
56 ])?,
57 })
58 }
59}
60
61#[derive(Debug, Arbitrary)]
73pub struct ArbitraryI2c<T> {
74 read_data: Vec<u8>,
75 maybe_error: Vec<Result<(), Error>>,
76 _p: PhantomData<T>,
77}
78
79impl<T> ArbitraryI2c<T> {
80 fn transaction_impl(&mut self, operations: &mut [Operation<'_>]) -> Result<(), Error> {
81 self.maybe_error.pop().ok_or(Error::default())??;
82 let operation_result: Result<Vec<_>, _> = operations
83 .iter_mut()
84 .map(|x| match x {
85 Operation::Read(read) => {
86 let result: Result<Vec<_>, Error> = read
87 .iter_mut()
88 .map(|x| {
89 *x = self.read_data.pop().ok_or(Error::default())?;
90 Ok(())
91 })
92 .collect();
93 result
94 }
95 Operation::Write(_) => Ok(Vec::new()),
96 })
97 .collect();
98 operation_result.map(|_| ())
99 }
100}
101
102impl<T> i2c::ErrorType for ArbitraryI2c<T> {
103 type Error = Error;
104}
105
106impl I2c<SevenBitAddress> for ArbitraryI2c<SevenBitAddress> {
107 fn transaction(
108 &mut self,
109 _address: u8,
110 operations: &mut [Operation<'_>],
111 ) -> Result<(), Self::Error> {
112 self.transaction_impl(operations)
113 }
114}
115
116impl I2c<TenBitAddress> for ArbitraryI2c<TenBitAddress> {
117 fn transaction(
118 &mut self,
119 _address: u16,
120 operations: &mut [Operation<'_>],
121 ) -> Result<(), Self::Error> {
122 self.transaction_impl(operations)
123 }
124}