use std::fmt::Debug;
use eh0 as embedded_hal;
use embedded_hal::adc::{Channel, OneShot};
use nb;
use super::error::MockError;
use crate::common::Generic;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Transaction<T> {
expected_chan: u8,
response: T,
err: Option<MockError>,
}
impl<T> Transaction<T> {
pub fn read(chan: u8, resp: T) -> Transaction<T> {
Transaction {
expected_chan: chan,
response: resp,
err: None,
}
}
pub fn with_error(mut self, error: MockError) -> Self {
self.err = Some(error);
self
}
}
pub struct MockAdc;
macro_rules! mock_channel {
($ADC:ident, $($pin:ident => $chan:expr),+ $(,)*) => {
$(
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct $pin;
impl Channel<$ADC> for $pin {
type ID = u8;
fn channel() -> u8 { $chan }
}
)+
};
}
mock_channel!(MockAdc,
MockChan0 => 0_u8,
MockChan1 => 1_u8,
MockChan2 => 2_u8,
);
pub type Mock<T> = Generic<Transaction<T>>;
impl<Pin, T> OneShot<MockAdc, T, Pin> for Mock<T>
where
Pin: Channel<MockAdc, ID = u8>,
T: Clone + Debug + PartialEq,
{
type Error = MockError;
fn read(&mut self, _pin: &mut Pin) -> nb::Result<T, Self::Error> {
let w = self.next().expect("unexpected read call");
assert_eq!(w.expected_chan, Pin::channel(), "unexpected channel");
match w.err {
Some(e) => Err(nb::Error::Other(e)),
None => Ok(w.response),
}
}
}
#[cfg(test)]
mod test {
use std::io::ErrorKind;
use eh0 as embedded_hal;
use embedded_hal::adc::OneShot;
use super::{super::error::MockError, *};
#[test]
fn test_adc_single_read16() {
let expectations = [Transaction::read(0, 0xabcdu16)];
let mut adc = Mock::new(&expectations);
assert_eq!(0xabcdu16, adc.read(&mut MockChan0 {}).unwrap());
adc.done();
}
#[test]
fn test_adc_single_read32() {
let expectations = [Transaction::read(0, 0xabcdabcdu32)];
let mut adc = Mock::new(&expectations);
assert_eq!(0xabcdabcdu32, adc.read(&mut MockChan0 {}).unwrap());
adc.done();
}
#[test]
fn test_adc_mult_read() {
let expectations = [
Transaction::read(0, 0xabcd),
Transaction::read(1, 0xabba),
Transaction::read(2, 0xbaab),
];
let mut adc = Mock::new(&expectations);
assert_eq!(0xabcd, adc.read(&mut MockChan0 {}).unwrap());
assert_eq!(0xabba, adc.read(&mut MockChan1 {}).unwrap());
assert_eq!(0xbaab, adc.read(&mut MockChan2 {}).unwrap());
adc.done();
}
#[test]
fn test_adc_err_read() {
let expectations = [
Transaction::read(0, 0xabcd),
Transaction::read(1, 0xabba).with_error(MockError::Io(ErrorKind::InvalidData)),
];
let mut adc = Mock::new(&expectations);
assert_eq!(0xabcd, adc.read(&mut MockChan0 {}).unwrap());
adc.read(&mut MockChan1 {})
.expect_err("expected error return");
adc.done();
}
}