diff --git a/Cargo.toml b/Cargo.toml index 021cd9f..31f4de7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "switch-hal" -version = "0.4.0" +version = "0.5.0" authors = ["Christopher J. McClellan "] edition = "2018" description = "HAL and basic implementations for input and output switches (buttons, switches, leds, transistors)" @@ -16,6 +16,19 @@ exclude = [ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = [] +async = ["dep:embedded-hal-async"] + [dependencies.embedded-hal] -version = "0.2.5" -features = [ "unproven" ] \ No newline at end of file +version = "1.0" + +[dependencies.embedded-hal-async] +version = "1.0" +optional = true + +[dev-dependencies.noop-waker] +version = "0.1" + +[dev-dependencies.assert_matches] +version = "1.5" \ No newline at end of file diff --git a/src/input/mod.rs b/src/input/mod.rs index 61ff01f..f44fafa 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,18 +1,70 @@ +#[cfg(feature = "async")] +use crate::WaitableInputSwitch; use crate::{ActiveHigh, ActiveLow, InputSwitch, Switch}; -use embedded_hal::digital::v2::InputPin; +use embedded_hal::digital::{ErrorType, InputPin}; +#[cfg(feature = "async")] +use embedded_hal_async::digital::Wait; impl InputSwitch for Switch { - type Error = ::Error; + type Error = ::Error; fn is_active(&self) -> Result { - self.pin.is_high() + self.pin.borrow_mut().is_high() } } impl InputSwitch for Switch { - type Error = ::Error; + type Error = ::Error; fn is_active(&self) -> Result { - self.pin.is_low() + self.pin.borrow_mut().is_low() + } +} + +#[cfg(feature = "async")] +impl WaitableInputSwitch for Switch +where + Switch: InputSwitch, +{ + type Error = ::Error; + + async fn wait_for_active(&mut self) -> Result<(), Self::Error> { + self.pin.get_mut().wait_for_high().await + } + + async fn wait_for_inactive(&mut self) -> Result<(), Self::Error> { + self.pin.get_mut().wait_for_low().await + } + + async fn wait_for_change(&mut self) -> Result<(), Self::Error> { + if self.pin.get_mut().is_high()? { + self.pin.get_mut().wait_for_low().await + } else { + self.pin.get_mut().wait_for_high().await + } + } +} + +#[cfg(feature = "async")] +impl WaitableInputSwitch for Switch +where + Switch: InputSwitch, +{ + type Error = ::Error; + + async fn wait_for_active(&mut self) -> Result<(), Self::Error> { + self.pin.get_mut().wait_for_low().await + } + + async fn wait_for_inactive(&mut self) -> Result<(), Self::Error> { + self.pin.get_mut().wait_for_high().await + } + + async fn wait_for_change(&mut self) -> Result<(), Self::Error> { + if self.pin.get_mut().is_high()? { + self.pin.get_mut().wait_for_low().await + } else { + self.pin.get_mut().wait_for_high().await + } } } diff --git a/src/lib.rs b/src/lib.rs index 1f8271f..8416339 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,7 @@ +//! "Async" feature enables async support for input switches. + #![no_std] +#![allow(async_fn_in_trait)] mod input; mod output; @@ -19,7 +22,7 @@ pub trait InputSwitch { /// use switch_hal::{InputSwitch, OutputSwitch, Switch, IntoSwitch}; /// # let pin = mock::Pin::with_state(mock::State::High); /// # let mut status_led = mock::Pin::new().into_active_high_switch(); - /// let button = pin.into_active_low_switch(); + /// let mut button = pin.into_active_low_switch(); /// match button.is_active() { /// Ok(true) => { status_led.on().ok(); } /// Ok(false) => { status_led.off().ok(); } @@ -29,6 +32,22 @@ pub trait InputSwitch { fn is_active(&self) -> Result; } +#[cfg(feature = "async")] +/// Represents an input switch that can be asynchronously waited for +pub trait WaitableInputSwitch { + type Error; + + /// Waits until the switch becomes active. If the switch in already active, returns immediately + /// + async fn wait_for_active(&mut self) -> Result<(), Self::Error>; + /// Waits until the switch becomes inactive. If the switch is already inactive, returns immediately + /// + async fn wait_for_inactive(&mut self) -> Result<(), Self::Error>; + /// Waits until the switch changess from active to inactive, or from inactive to active + /// + async fn wait_for_change(&mut self) -> Result<(), Self::Error>; +} + /// Represents an output switch, such as a LED "switch" or transistor pub trait OutputSwitch { type Error; @@ -63,11 +82,11 @@ pub trait OutputSwitch { /// Toggles the switch from it's current state to it's opposite state. /// /// # Notes -/// This is only available if the underlying hal has implemented [ToggleableOutputPin](embedded_hal::digital::v2::ToggleableOutputPin) +/// This is only available if the underlying hal has implemented [StatefulOutputPin](embedded_hal::digital::StatefulOutputPin) pub trait ToggleableOutputSwitch { type Error; - /// Toggles the current state of the [OutputSwitch](OutputSwitch) + /// Toggles the current state of the [OutputSwitch] /// /// # Examples /// @@ -84,7 +103,7 @@ pub trait ToggleableOutputSwitch { /// Checks current switch state /// /// # Notes -/// This is only available if the underlying hal has implemented [StatefulOutputPin](embedded_hal::digital::v2::StatefulOutputPin) +/// This is only available if the underlying hal has implemented [StatefulOutputPin](embedded_hal::digital::StatefulOutputPin) pub trait StatefulOutputSwitch { type Error; @@ -98,7 +117,7 @@ pub trait StatefulOutputSwitch { /// # let pin = mock::Pin::new(); /// let mut led = pin.into_active_high_switch(); /// led.off().ok(); - /// assert!(!led.is_on().unwrap()); + /// assert_eq!(false, led.is_on().unwrap()); /// ``` fn is_on(&mut self) -> Result; @@ -112,7 +131,7 @@ pub trait StatefulOutputSwitch { /// # let pin = mock::Pin::new(); /// let mut led = pin.into_active_high_switch(); /// led.off().ok(); - /// assert!(led.is_off().unwrap()); + /// assert_eq!(true, led.is_off().unwrap()); /// ``` fn is_off(&mut self) -> Result; } @@ -122,23 +141,23 @@ pub struct ActiveHigh; /// Zero sized struct for signaling to [Switch](struct.Switch.html) that it is active low pub struct ActiveLow; -use core::marker::PhantomData; +use core::{cell::RefCell, marker::PhantomData}; /// Concrete implementation for [InputSwitch](trait.InputSwitch.html) and [OutputSwitch](trait.OutputSwitch.html) /// /// # Type Params -/// - `IoPin` must be a type that implements either of the [InputPin](embedded_hal::digital::v2::InputPin) or [OutputPin](embedded_hal::digital::v2::OutputPin) traits. -/// - `ActiveLevel` indicates whether the `Switch` is [ActiveHigh](ActiveHigh) or [ActiveLow](ActiveLow). +/// - `IoPin` must be a type that implements either of the [InputPin](embedded_hal::digital::InputPin) or [OutputPin](embedded_hal::digital::OutputPin) traits. +/// - `ActiveLevel` indicates whether the `Switch` is [ActiveHigh] or [ActiveLow]. /// `ActiveLevel` is not actually stored in the struct. -/// It's [PhantomData](core::marker::PhantomData) used to indicate which implementation to use. +/// It's [PhantomData] used to indicate which implementation to use. pub struct Switch { - pin: IoPin, + pin: RefCell, active: PhantomData, } impl Switch { /// Constructs a new [Switch](struct.Switch.html) from a concrete implementation of an - /// [InputPin](embedded_hal::digital::v2::InputPin) or [OutputPin](embedded_hal::digital::v2::OutputPin) + /// [InputPin](embedded_hal::digital::InputPin) or [OutputPin](embedded_hal::digital::OutputPin) /// /// **Prefer the [IntoSwitch](trait.IntoSwitch.html) trait over calling [new](#method.new) directly.** /// @@ -183,12 +202,12 @@ impl Switch { /// ``` pub fn new(pin: IoPin) -> Self { Switch { - pin: pin, + pin: RefCell::new(pin), active: PhantomData::, } } - /// Consumes the [Switch](struct.Switch.html) and returns the underlying [InputPin](embedded_hal::digital::v2::InputPin) or [OutputPin](embedded_hal::digital::v2::OutputPin). + /// Consumes the [Switch](struct.Switch.html) and returns the underlying [InputPin](embedded_hal::digital::InputPin) or [OutputPin](embedded_hal::digital::OutputPin). /// /// This is useful fore retrieving the underlying pin to use it for a different purpose. /// @@ -204,19 +223,18 @@ impl Switch { /// // do something else with the pin /// ``` pub fn into_pin(self) -> IoPin { - self.pin + self.pin.into_inner() } } -/// Convenience functions for converting [InputPin](embedded_hal::digital::v2::InputPin) -/// and [OutputPin](embedded_hal::digital::v2::OutputPin) to a [Switch](struct.Switch.html). +/// Convenience functions for converting [InputPin](embedded_hal::digital::InputPin) +/// and [OutputPin](embedded_hal::digital::OutputPin) to a [Switch](struct.Switch.html). /// /// The type of [Switch](struct.Switch.html) returned, /// [InputSwitch](trait.InputSwitch.html) or [OutputSwitch](trait.OutputSwitch.html) is -/// determined by whether the `IoPin` being consumed is an [InputPin](embedded_hal::digital::v2::InputPin) -/// or [OutputPin](embedded_hal::digital::v2::OutputPin). +/// determined by whether the `IoPin` being consumed is an [InputPin](embedded_hal::digital::InputPin) +/// or [OutputPin](embedded_hal::digital::OutputPin). pub trait IntoSwitch { - /// Consumes the `IoPin` returning a [Switch](struct.Switch.html) of the appropriate `ActiveLevel`. /// /// This method exists so other, more convenient functions, can have blanket implementations. diff --git a/src/mock.rs b/src/mock.rs index f839299..a38c1f8 100644 --- a/src/mock.rs +++ b/src/mock.rs @@ -1,12 +1,18 @@ -//! Mock implementations of [InputPin](embedded_hal::digital::v2::InputPin) and [OutputPin](embedded_hal::digital::v2::OutputPin). +//! Mock implementations of [InputPin] and [OutputPin] //! //! WARNING: May be removed if `embedded_hal_mock` crate is improved. -//! https://github.com/dbrgn/embedded-hal-mock/issues/30 +//! //! //! This is part of the main crate so it is accessible to doctests. //! Otherwise, I would have created a tests/mock/mod.rs file. -use embedded_hal::digital::v2::toggleable; -use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; + +#![allow(clippy::bool_assert_comparison)] + +use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin}; +#[cfg(feature = "async")] +use embedded_hal_async::digital::Wait; +#[cfg(feature = "async")] +use core::{future::poll_fn, task::Poll}; #[derive(PartialEq, Eq, Debug)] pub enum State { @@ -18,6 +24,12 @@ pub struct Pin { state: Option, } +impl Default for Pin { + fn default() -> Self { + Self::new() + } +} + impl Pin { pub fn new() -> Self { Pin { state: None } @@ -28,20 +40,30 @@ impl Pin { } } -type MockError = &'static str; +#[derive(Debug)] +#[allow(dead_code)] +pub struct MockError(&'static str); -impl InputPin for Pin { +impl embedded_hal::digital::Error for MockError { + fn kind(&self) -> embedded_hal::digital::ErrorKind { + embedded_hal::digital::ErrorKind::Other + } +} + +impl ErrorType for Pin { type Error = MockError; +} - fn is_high(&self) -> Result { +impl InputPin for Pin { + fn is_high(&mut self) -> Result { match self.state { Some(State::High) => Ok(true), Some(State::Low) => Ok(false), - None => Err("state not set"), + None => Err(MockError("state not set")), } } - fn is_low(&self) -> Result { + fn is_low(&mut self) -> Result { match self.is_high() { Ok(v) => Ok(!v), Err(e) => Err(e), @@ -50,8 +72,6 @@ impl InputPin for Pin { } impl OutputPin for Pin { - type Error = MockError; - fn set_low(&mut self) -> Result<(), Self::Error> { self.state = Some(State::Low); Ok(()) @@ -64,16 +84,57 @@ impl OutputPin for Pin { } impl StatefulOutputPin for Pin { - fn is_set_low(&self) -> Result { + fn is_set_low(&mut self) -> Result { self.is_low() } - fn is_set_high(&self) -> Result { + fn is_set_high(&mut self) -> Result { self.is_high() } } -impl toggleable::Default for Pin {} +#[cfg(feature = "async")] +impl Wait for Pin { + async fn wait_for_high(&mut self) -> Result<(), Self::Error> { + poll_fn(|_cx| { + if self.state == Some(State::High) { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + }) + .await + } + + async fn wait_for_low(&mut self) -> Result<(), Self::Error> { + poll_fn(|_cx| { + if self.state == Some(State::Low) { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + }) + .await + } + + async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_low().await?; + self.wait_for_high().await + } + + async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_high().await?; + self.wait_for_low().await + } + + async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> { + if self.is_high()? { + self.wait_for_falling_edge().await + } else { + self.wait_for_rising_edge().await + } + } +} #[cfg(test)] mod test { @@ -84,7 +145,7 @@ mod test { #[test] fn state_is_uninitialized() { - let pin = Pin::new(); + let mut pin = Pin::new(); assert_eq!(None, pin.state); pin.is_low().expect_err("Expected uninitialized pin"); } @@ -95,7 +156,7 @@ mod test { #[test] fn error_when_uninitialized() { - let pin = Pin { state: None }; + let mut pin = Pin { state: None }; pin.is_high().expect_err("Expected uninitialized pin"); } @@ -104,13 +165,13 @@ mod test { #[test] fn returns_true_when_state_is_high() { - let pin = Pin::with_state(State::High); + let mut pin = Pin::with_state(State::High); assert_eq!(true, pin.is_high().unwrap()); } #[test] fn returns_false_when_state_is_low() { - let pin = Pin::with_state(State::Low); + let mut pin = Pin::with_state(State::Low); assert_eq!(false, pin.is_high().unwrap()); } } @@ -120,16 +181,86 @@ mod test { #[test] fn returns_false_when_state_is_high() { - let pin = Pin::with_state(State::High); + let mut pin = Pin::with_state(State::High); assert_eq!(false, pin.is_low().unwrap()); } #[test] fn returns_true_when_state_is_high() { - let pin = Pin::with_state(State::Low); + let mut pin = Pin::with_state(State::Low); assert_eq!(true, pin.is_low().unwrap()); } } + + #[cfg(feature = "async")] + mod asynch { + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll}; + use noop_waker::noop_waker; + + use super::*; + + #[test] + fn wait_for_high_while_high() { + let mut pin = Pin::with_state(State::High); + let mut future = pin!(pin.wait_for_high()); + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(true, matches!(future.as_mut().poll(&mut cx), Poll::Ready(_))) + } + + #[test] + fn wait_for_high_while_low() { + let mut pin = Pin::with_state(State::Low); + let mut future = pin!(pin.wait_for_high()); + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(true, matches!(future.as_mut().poll(&mut cx), Poll::Pending)); + } + + #[test] + fn wait_for_low_while_low() { + let mut pin = Pin::with_state(State::Low); + let mut future = pin!(pin.wait_for_low()); + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(true, matches!(future.as_mut().poll(&mut cx), Poll::Ready(_))); + } + + #[test] + fn wait_for_low_while_high() { + let mut pin = Pin::with_state(State::High); + let mut future = pin!(pin.wait_for_low()); + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(true, matches!(future.as_mut().poll(&mut cx), Poll::Pending)); + } + + #[test] + fn wait_for_any_edge_while_high() { + let mut pin = Pin::with_state(State::High); + let mut future = pin!(pin.wait_for_any_edge()); + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(true, matches!(future.as_mut().poll(&mut cx), Poll::Pending)); + } + + #[test] + fn wait_for_any_edge_while_low() { + let mut pin = Pin::with_state(State::Low); + let mut future = pin!(pin.wait_for_any_edge()); + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(true, matches!(future.as_mut().poll(&mut cx), Poll::Pending)); + } + } } mod output_pin { @@ -157,7 +288,7 @@ mod test { #[test] fn error_when_uninitialized() { - let pin = Pin { state: None }; + let mut pin = Pin { state: None }; pin.is_set_high().expect_err("Expected uninitialized pin"); } @@ -166,13 +297,13 @@ mod test { #[test] fn returns_false_when_state_is_high() { - let pin = Pin::with_state(State::High); + let mut pin = Pin::with_state(State::High); assert_eq!(false, pin.is_set_low().unwrap()); } #[test] fn returns_true_when_state_is_high() { - let pin = Pin::with_state(State::Low); + let mut pin = Pin::with_state(State::Low); assert_eq!(true, pin.is_set_low().unwrap()); } } @@ -182,20 +313,20 @@ mod test { #[test] fn returns_true_when_state_is_high() { - let pin = Pin::with_state(State::High); + let mut pin = Pin::with_state(State::High); assert_eq!(true, pin.is_set_high().unwrap()); } #[test] fn returns_false_when_state_is_low() { - let pin = Pin::with_state(State::Low); + let mut pin = Pin::with_state(State::Low); assert_eq!(false, pin.is_set_high().unwrap()); } } mod toggleable { use super::*; - use embedded_hal::digital::v2::ToggleableOutputPin; + use embedded_hal::digital::StatefulOutputPin; #[test] fn default_toggleable_impl() { diff --git a/src/output/mod.rs b/src/output/mod.rs index fbacf86..7c1fad6 100644 --- a/src/output/mod.rs +++ b/src/output/mod.rs @@ -1,65 +1,63 @@ -use embedded_hal::digital::v2::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; +use embedded_hal::digital::{ErrorType, OutputPin, StatefulOutputPin}; -use crate::{ActiveHigh, ActiveLow, OutputSwitch, Switch, StatefulOutputSwitch, ToggleableOutputSwitch}; +use crate::{ + ActiveHigh, ActiveLow, OutputSwitch, StatefulOutputSwitch, Switch, ToggleableOutputSwitch, +}; impl OutputSwitch for Switch { - type Error = ::Error; + type Error = ::Error; fn on(&mut self) -> Result<(), Self::Error> { - self.pin.set_high() + self.pin.borrow_mut().set_high() } fn off(&mut self) -> Result<(), Self::Error> { - self.pin.set_low() + self.pin.borrow_mut().set_low() } } impl OutputSwitch for Switch { - type Error = ::Error; + type Error = ::Error; fn on(&mut self) -> Result<(), Self::Error> { - self.pin.set_low() + self.pin.borrow_mut().set_low() } fn off(&mut self) -> Result<(), Self::Error> { - self.pin.set_high() + self.pin.borrow_mut().set_high() } } -impl ToggleableOutputSwitch +impl ToggleableOutputSwitch for Switch { - type Error = ::Error; + type Error = ::Error; fn toggle(&mut self) -> Result<(), Self::Error> { - self.pin.toggle() + self.pin.get_mut().toggle() } } -impl StatefulOutputSwitch - for Switch -{ - type Error = ::Error; +impl StatefulOutputSwitch for Switch { + type Error = ::Error; fn is_on(&mut self) -> Result { - self.pin.is_set_low() + self.pin.get_mut().is_set_low() } fn is_off(&mut self) -> Result { - self.pin.is_set_high() + self.pin.get_mut().is_set_high() } } -impl StatefulOutputSwitch - for Switch -{ - type Error = ::Error; +impl StatefulOutputSwitch for Switch { + type Error = ::Error; fn is_on(&mut self) -> Result { - self.pin.is_set_high() + self.pin.get_mut().is_set_high() } fn is_off(&mut self) -> Result { - self.pin.is_set_low() + self.pin.get_mut().is_set_low() } } diff --git a/tests/input.rs b/tests/input.rs index 6688c8d..a5547c8 100644 --- a/tests/input.rs +++ b/tests/input.rs @@ -1,3 +1,4 @@ +#![allow(clippy::bool_assert_comparison)] extern crate switch_hal; use switch_hal::mock::{Pin, State}; @@ -31,7 +32,9 @@ mod active_high_switch { fn propagates_errors_from_pin() { let pin = Pin::new(); let button = Switch::<_, ActiveHigh>::new(pin); - button.is_active().expect_err("Expected uninitialized error"); + button + .is_active() + .expect_err("Expected uninitialized error"); } } } @@ -64,7 +67,9 @@ mod active_low_switch { fn propagates_errors_from_pin() { let pin = Pin::new(); let button = Switch::<_, ActiveLow>::new(pin); - button.is_active().expect_err("Expected uninitialized error"); + button + .is_active() + .expect_err("Expected uninitialized error"); } } } diff --git a/tests/output.rs b/tests/output.rs index 7015b93..81f5697 100644 --- a/tests/output.rs +++ b/tests/output.rs @@ -1,10 +1,11 @@ +#![allow(clippy::bool_assert_comparison)] extern crate switch_hal; use switch_hal::mock; mod active_high_switch { use super::*; - use embedded_hal::digital::v2::InputPin; + use embedded_hal::digital::InputPin; use switch_hal::{ActiveHigh, OutputSwitch, Switch}; #[test] @@ -14,7 +15,7 @@ mod active_high_switch { let mut led = Switch::<_, ActiveHigh>::new(pin); led.on().unwrap(); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_high().unwrap()); } @@ -25,7 +26,7 @@ mod active_high_switch { let mut led = Switch::<_, ActiveHigh>::new(pin); led.off().unwrap(); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_low().unwrap()); } @@ -40,7 +41,7 @@ mod active_high_switch { led.toggle().unwrap(); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_high().unwrap()); } @@ -55,7 +56,7 @@ mod active_high_switch { assert_eq!(false, led.is_on().unwrap()); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(false, pin.is_high().unwrap()); } @@ -70,14 +71,14 @@ mod active_high_switch { assert_eq!(true, led.is_on().unwrap()); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_high().unwrap()); } } mod active_low_switch { use super::*; - use embedded_hal::digital::v2::InputPin; + use embedded_hal::digital::InputPin; use switch_hal::{ActiveLow, OutputSwitch, Switch}; #[test] @@ -87,7 +88,7 @@ mod active_low_switch { let mut led = Switch::<_, ActiveLow>::new(pin); led.on().unwrap(); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_low().unwrap()); } @@ -98,7 +99,7 @@ mod active_low_switch { let mut led = Switch::<_, ActiveLow>::new(pin); led.off().unwrap(); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_high().unwrap()); } @@ -113,7 +114,7 @@ mod active_low_switch { led.toggle().unwrap(); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_low().unwrap()); } @@ -128,7 +129,7 @@ mod active_low_switch { assert_eq!(false, led.is_on().unwrap()); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(false, pin.is_low().unwrap()); } @@ -143,7 +144,7 @@ mod active_low_switch { assert_eq!(true, led.is_on().unwrap()); - let pin = led.into_pin(); + let mut pin = led.into_pin(); assert_eq!(true, pin.is_low().unwrap()); } } diff --git a/tests/pin_into_switch.rs b/tests/pin_into_switch.rs index a6fd435..6a537b0 100644 --- a/tests/pin_into_switch.rs +++ b/tests/pin_into_switch.rs @@ -1,10 +1,11 @@ +#![allow(clippy::bool_assert_comparison)] use switch_hal::mock::{Pin, State}; use switch_hal::IntoSwitch; mod output_pin { use super::*; - use embedded_hal::digital::v2::InputPin; + use embedded_hal::digital::InputPin; use switch_hal::OutputSwitch; #[test] @@ -13,7 +14,7 @@ mod output_pin { let mut switch = pin.into_active_high_switch(); switch.on().unwrap(); - let pin = switch.into_pin(); + let mut pin = switch.into_pin(); assert_eq!(true, pin.is_high().unwrap()); } @@ -23,7 +24,7 @@ mod output_pin { let mut switch = pin.into_active_low_switch(); switch.on().unwrap(); - let pin = switch.into_pin(); + let mut pin = switch.into_pin(); assert_eq!(true, pin.is_low().unwrap()); } }