Skip to content

[0.2.x] Fixes to digital compatibility shim #220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Fix the input pin v2->v1 compatibility shim constructor, where `OldInputPin::new`
was incorrectly implemented for `v1::OutputPin` values.


## [v0.2.3] - 2019-05-09

Expand Down
54 changes: 43 additions & 11 deletions src/digital/v1_compat.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
//! v1 compatibility wrapper
//! this module adds reverse support for v2 digital traits
//! v2 traits must be explicitly cast to the v1 version using `.into()`,
//! and will panic on internal errors
//! v1 compatibility wrappers
//!
//! This module provides wrappers to support use of v2 implementations with
//! v1 consumers. v2 traits must be explicitly cast to the v1 version using
//! `.into()`, and will panic on internal errors
//!
//! ```
//! extern crate embedded_hal;
//! use embedded_hal::digital::{v1, v2, v1_compat::OldOutputPin};
//!
//! struct NewOutputPinImpl {}
//!
//! impl v2::OutputPin for NewOutputPinImpl {
//! type Error = ();
//! fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) }
//! fn set_high(&mut self) -> Result<(), Self::Error>{ Ok(()) }
//! }
//!
//! struct OldOutputPinConsumer<T: v1::OutputPin> {
//! _pin: T,
//! }
//!
//! impl <T>OldOutputPinConsumer<T>
//! where T: v1::OutputPin {
//! pub fn new(pin: T) -> OldOutputPinConsumer<T> {
//! OldOutputPinConsumer{ _pin: pin }
//! }
//! }
//!
//! fn main() {
//! let pin = NewOutputPinImpl{};
//! let _consumer: OldOutputPinConsumer<OldOutputPin<_>> = OldOutputPinConsumer::new(pin.into());
//! }
//! ```
//!


#[allow(deprecated)]
use super::v1;
Expand Down Expand Up @@ -60,7 +92,7 @@ where
/// where errors will panic.
#[cfg(feature = "unproven")]
#[allow(deprecated)]
impl <T, E> v1::StatefulOutputPin for OldOutputPin<T>
impl <T, E> v1::StatefulOutputPin for OldOutputPin<T>
where
T: v2::StatefulOutputPin<Error=E>,
E: core::fmt::Debug,
Expand All @@ -84,7 +116,7 @@ pub struct OldInputPin<T> {
#[cfg(feature = "unproven")]
impl <T, E> OldInputPin<T>
where
T: v2::OutputPin<Error=E>,
T: v2::InputPin<Error=E>,
E: core::fmt::Debug,
{
/// Create an `OldInputPin` wrapper around a `v2::InputPin`.
Expand Down Expand Up @@ -159,8 +191,8 @@ mod tests {
}

#[allow(deprecated)]
impl <T>OldOutputPinConsumer<T>
where T: v1::OutputPin
impl <T>OldOutputPinConsumer<T>
where T: v1::OutputPin
{
pub fn new(pin: T) -> OldOutputPinConsumer<T> {
OldOutputPinConsumer{ _pin: pin }
Expand All @@ -181,7 +213,7 @@ mod tests {
assert_eq!(o.inner().state, true);

o.set_low();
assert_eq!(o.inner().state, false);
assert_eq!(o.inner().state, false);
}

#[test]
Expand Down Expand Up @@ -220,8 +252,8 @@ mod tests {

#[cfg(feature = "unproven")]
#[allow(deprecated)]
impl <T>OldInputPinConsumer<T>
where T: v1::InputPin
impl <T>OldInputPinConsumer<T>
where T: v1::InputPin
{
pub fn new(pin: T) -> OldInputPinConsumer<T> {
OldInputPinConsumer{ _pin: pin }
Expand Down
69 changes: 68 additions & 1 deletion src/digital/v2_compat.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
//! v2 compatibility shims
//! this module adds implicit forward support to v1 digital traits
//!
//! This module adds implicit forward support to v1 digital traits,
//! allowing v1 implementations to be directly used with v2 consumers.
//!
//! ```
//! extern crate embedded_hal;
//! use embedded_hal::digital::{v1, v2};
//!
//! struct OldOutputPinImpl { }
//!
//! impl v1::OutputPin for OldOutputPinImpl {
//! fn set_low(&mut self) { }
//! fn set_high(&mut self) { }
//! }
//!
//! struct NewOutputPinConsumer<T: v2::OutputPin> {
//! _pin: T,
//! }
//!
//! impl <T>NewOutputPinConsumer<T>
//! where T: v2::OutputPin {
//! pub fn new(pin: T) -> NewOutputPinConsumer<T> {
//! NewOutputPinConsumer{ _pin: pin }
//! }
//! }
//!
//! fn main() {
//! let pin = OldOutputPinImpl{};
//! let _consumer = NewOutputPinConsumer::new(pin);
//! }
//! ```
//!

#[allow(deprecated)]
use super::v1;
Expand Down Expand Up @@ -39,6 +70,9 @@ where
}
}

#[cfg(feature = "unproven")]
#[allow(deprecated)]
impl<T> v2::toggleable::Default for T where T: v1::toggleable::Default {}

/// Implementation of fallible `v2::InputPin` for `v1::InputPin` digital traits
#[cfg(feature = "unproven")]
Expand Down Expand Up @@ -81,6 +115,20 @@ mod tests {
}
}

#[allow(deprecated)]
impl v1::StatefulOutputPin for OldOutputPinImpl {
fn is_set_low(&self) -> bool {
self.state == false
}

fn is_set_high(&self) -> bool {
self.state == true
}
}

#[allow(deprecated)]
impl v1::toggleable::Default for OldOutputPinImpl {}

struct NewOutputPinConsumer<T: v2::OutputPin> {
_pin: T,
}
Expand All @@ -92,6 +140,25 @@ mod tests {
}
}

struct NewToggleablePinConsumer<T: v2::ToggleableOutputPin> {
_pin: T,
}

impl<T> NewToggleablePinConsumer<T>
where
T: v2::ToggleableOutputPin,
{
pub fn new(pin: T) -> NewToggleablePinConsumer<T> {
NewToggleablePinConsumer { _pin: pin }
}
}

#[test]
fn v2_v1_toggleable_implicit() {
let i = OldOutputPinImpl { state: false };
let _c = NewToggleablePinConsumer::new(i);
}

#[test]
fn v2_v1_output_implicit() {
let i = OldOutputPinImpl{state: false};
Expand Down