diff --git a/CHANGELOG.md b/CHANGELOG.md index bfa9671e4..2f7ef0201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). fallible and their methods now return a `Result` type as setting an output pin and reading an input pin could potentially fail. See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info. +- Compatibility shims between `digital::v1` and `digital::v2` traits allowing v1 traits + to be implicitly promoted to v2, and for v2 traits to be explicitly cast to v1 wrappers. ### Changed - The current versions of the `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin` diff --git a/src/digital/mod.rs b/src/digital/mod.rs index 5784f0fbe..4e67f9851 100644 --- a/src/digital/mod.rs +++ b/src/digital/mod.rs @@ -1,155 +1,25 @@ //! Digital I/O //! -//! The traits in this module are now deprecated. Please use the new versions included -//! in `digital::v2`. - -/// Single digital push-pull output pin -/// -/// *This version of the trait is now deprecated. Please use the new `OutputPin` trait in -/// `digital::v2::OutputPin`*. -#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \ - Users should use the traits in digital::v2.")] -pub trait OutputPin { - /// Drives the pin low - /// - /// *NOTE* the actual electrical state of the pin may not actually be low, e.g. due to external - /// electrical sources - fn set_low(&mut self); - - /// Drives the pin high - /// - /// *NOTE* the actual electrical state of the pin may not actually be high, e.g. due to external - /// electrical sources - fn set_high(&mut self); -} - -/// Push-pull output pin that can read its output state -/// -/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* -/// -/// *This version of the trait is now deprecated. Please use the new `StatefulOutputPin` trait in -/// `digital::v2::StatefulOutputPin`*. -#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \ - Users should use the traits in digital::v2.")] -#[cfg(feature = "unproven")] -pub trait StatefulOutputPin { - /// Is the pin in drive high mode? - /// - /// *NOTE* this does *not* read the electrical state of the pin - fn is_set_high(&self) -> bool; - - /// Is the pin in drive low mode? - /// - /// *NOTE* this does *not* read the electrical state of the pin - fn is_set_low(&self) -> bool; -} - -/// Output pin that can be toggled -/// -/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* -/// -/// *This version of the trait is now deprecated. Please use the new `ToggleableOutputPin` -/// trait in `digital::v2::ToggleableOutputPin`*. -/// -/// See [toggleable](toggleable) to use a software implementation if -/// both [OutputPin](trait.OutputPin.html) and -/// [StatefulOutputPin](trait.StatefulOutputPin.html) are -/// implemented. Otherwise, implement this using hardware mechanisms. -#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \ - Users should use the traits in digital::v2.")] -#[cfg(feature = "unproven")] -pub trait ToggleableOutputPin { - /// Toggle pin output. - fn toggle(&mut self); -} +//! +//! -/// If you can read **and** write the output state, a pin is -/// toggleable by software. -/// -/// *This version of the module is now deprecated. Please use the new `toggleable` module in -/// `digital::v2::toggleable`*. -/// -/// ``` -/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; -/// use embedded_hal::digital::toggleable; -/// -/// /// A virtual output pin that exists purely in software -/// struct MyPin { -/// state: bool -/// } -/// -/// impl OutputPin for MyPin { -/// fn set_low(&mut self) { -/// self.state = false; -/// } -/// fn set_high(&mut self) { -/// self.state = true; -/// } -/// } -/// -/// impl StatefulOutputPin for MyPin { -/// fn is_set_low(&self) -> bool { -/// !self.state -/// } -/// fn is_set_high(&self) -> bool { -/// self.state -/// } -/// } -/// -/// /// Opt-in to the software implementation. -/// impl toggleable::Default for MyPin {} -/// -/// let mut pin = MyPin { state: false }; -/// pin.toggle(); -/// assert!(pin.is_set_high()); -/// pin.toggle(); -/// assert!(pin.is_set_low()); -/// ``` +// Deprecated / infallible traits #[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \ Users should use the traits in digital::v2.")] -#[cfg(feature = "unproven")] -pub mod toggleable { - #[allow(deprecated)] - use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; +pub mod v1; - /// Software-driven `toggle()` implementation. - /// - /// *This trait is available if embedded-hal is built with the `"unproven"` feature.* - #[allow(deprecated)] - pub trait Default: OutputPin + StatefulOutputPin {} +// New / fallible traits +pub mod v2; - #[allow(deprecated)] - impl
ToggleableOutputPin for P - where - P: Default, - { - /// Toggle pin output - fn toggle(&mut self) { - if self.is_set_low() { - self.set_high(); - } else { - self.set_low(); - } - } - } -} +// v2 -> v1 compatibility wrappers +// These require explicit casts from v2 -> v1 +pub mod v1_compat; -/// Single digital input pin -/// -/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* -/// -/// *This version of the trait is now deprecated. Please use the new `InputPin` trait in -/// `digital::v2::InputPin`*. -#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \ - Users should use the traits in digital::v2.")] -#[cfg(feature = "unproven")] -pub trait InputPin { - /// Is the input pin high? - fn is_high(&self) -> bool; +// v1 -> v2 compatibility shims +// These are implicit over v1 implementations +pub mod v2_compat; - /// Is the input pin low? - fn is_low(&self) -> bool; -} +// Re-export old traits so this isn't a breaking change +#[allow(deprecated)] +pub use self::v1::*; -/// Improved version of the digital traits where the methods can also return an error. -pub mod v2; diff --git a/src/digital/v1.rs b/src/digital/v1.rs new file mode 100644 index 000000000..d7bbfacaa --- /dev/null +++ b/src/digital/v1.rs @@ -0,0 +1,145 @@ +//! Digital I/O +//! +//! The traits in this module are now deprecated. Please use the new versions included +//! in `digital::v2`. + +#![allow(deprecated)] + +/// Single digital push-pull output pin +/// +/// *This version of the trait is now deprecated. Please use the new `OutputPin` trait in +/// `digital::v2::OutputPin`*. + +pub trait OutputPin { + /// Drives the pin low + /// + /// *NOTE* the actual electrical state of the pin may not actually be low, e.g. due to external + /// electrical sources + fn set_low(&mut self); + + /// Drives the pin high + /// + /// *NOTE* the actual electrical state of the pin may not actually be high, e.g. due to external + /// electrical sources + fn set_high(&mut self); +} + +/// Push-pull output pin that can read its output state +/// +/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* +/// +/// *This version of the trait is now deprecated. Please use the new `StatefulOutputPin` trait in +/// `digital::v2::StatefulOutputPin`*. +#[cfg(feature = "unproven")] +pub trait StatefulOutputPin { + /// Is the pin in drive high mode? + /// + /// *NOTE* this does *not* read the electrical state of the pin + fn is_set_high(&self) -> bool; + + /// Is the pin in drive low mode? + /// + /// *NOTE* this does *not* read the electrical state of the pin + fn is_set_low(&self) -> bool; +} + +/// Output pin that can be toggled +/// +/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* +/// +/// *This version of the trait is now deprecated. Please use the new `ToggleableOutputPin` +/// trait in `digital::v2::ToggleableOutputPin`*. +/// +/// See [toggleable](toggleable) to use a software implementation if +/// both [OutputPin](trait.OutputPin.html) and +/// [StatefulOutputPin](trait.StatefulOutputPin.html) are +/// implemented. Otherwise, implement this using hardware mechanisms. +#[cfg(feature = "unproven")] +pub trait ToggleableOutputPin { + /// Toggle pin output. + fn toggle(&mut self); +} + +/// If you can read **and** write the output state, a pin is +/// toggleable by software. +/// +/// *This version of the module is now deprecated. Please use the new `toggleable` module in +/// `digital::v2::toggleable`*. +/// +/// ``` +/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; +/// use embedded_hal::digital::toggleable; +/// +/// /// A virtual output pin that exists purely in software +/// struct MyPin { +/// state: bool +/// } +/// +/// impl OutputPin for MyPin { +/// fn set_low(&mut self) { +/// self.state = false; +/// } +/// fn set_high(&mut self) { +/// self.state = true; +/// } +/// } +/// +/// impl StatefulOutputPin for MyPin { +/// fn is_set_low(&self) -> bool { +/// !self.state +/// } +/// fn is_set_high(&self) -> bool { +/// self.state +/// } +/// } +/// +/// /// Opt-in to the software implementation. +/// impl toggleable::Default for MyPin {} +/// +/// let mut pin = MyPin { state: false }; +/// pin.toggle(); +/// assert!(pin.is_set_high()); +/// pin.toggle(); +/// assert!(pin.is_set_low()); +/// ``` +#[cfg(feature = "unproven")] +pub mod toggleable { + #[allow(deprecated)] + use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; + + /// Software-driven `toggle()` implementation. + /// + /// *This trait is available if embedded-hal is built with the `"unproven"` feature.* + #[allow(deprecated)] + pub trait Default: OutputPin + StatefulOutputPin {} + + #[allow(deprecated)] + impl
ToggleableOutputPin for P
+ where
+ P: Default,
+ {
+ /// Toggle pin output
+ fn toggle(&mut self) {
+ if self.is_set_low() {
+ self.set_high();
+ } else {
+ self.set_low();
+ }
+ }
+ }
+}
+
+/// Single digital input pin
+///
+/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
+///
+/// *This version of the trait is now deprecated. Please use the new `InputPin` trait in
+/// `digital::v2::InputPin`*.
+#[cfg(feature = "unproven")]
+pub trait InputPin {
+ /// Is the input pin high?
+ fn is_high(&self) -> bool;
+
+ /// Is the input pin low?
+ fn is_low(&self) -> bool;
+}
diff --git a/src/digital/v1_compat.rs b/src/digital/v1_compat.rs
new file mode 100644
index 000000000..aed9aaf7a
--- /dev/null
+++ b/src/digital/v1_compat.rs
@@ -0,0 +1,256 @@
+//! 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
+
+#[allow(deprecated)]
+use super::v1;
+use super::v2;
+
+/// Wrapper to allow fallible `v2::OutputPin` traits to be converted to `v1::OutputPin` traits
+pub struct OldOutputPin