Skip to content
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

Add fallible version of the digital traits and deprecate the current ones #108

Merged
merged 3 commits into from
Dec 11, 2018
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added
- A new version of the digital `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
and `InputPin` traits has been added under `digital::v2`. These traits are now
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.

### Changed
- The current versions of the `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
and `InputPin` traits have been marked as deprecated. Please use the new versions
included in `digital::v2`.
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.


## [v0.2.2] - 2018-11-03

### Added
Expand All @@ -21,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Updated docs to clarify I2C address bit widths and expectations.


## [v0.2.1] - 2018-05-14

### Changed
Expand Down
155 changes: 155 additions & 0 deletions src/digital/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//! 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(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};

/// 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<P> 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`*.
#[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;

/// Is the input pin low?
fn is_low(&self) -> bool;
}

/// Improved version of the digital traits where the methods can also return an error.
pub mod v2;
65 changes: 40 additions & 25 deletions src/digital.rs → src/digital/v2.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
//! Digital I/O
/// Digital I/O

/// Single digital push-pull output pin
pub trait OutputPin {
/// Error type
type Error;

/// 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);
fn set_low(&mut self) -> Result<(), Self::Error>;

/// 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);
fn set_high(&mut self) -> Result<(), Self::Error>;
}

/// Push-pull output pin that can read its output state
///
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
#[cfg(feature = "unproven")]
pub trait StatefulOutputPin {
pub trait StatefulOutputPin : OutputPin {
/// Is the pin in drive high mode?
///
/// *NOTE* this does *not* read the electrical state of the pin
fn is_set_high(&self) -> bool;
fn is_set_high(&self) -> Result<bool, Self::Error>;

/// Is the pin in drive low mode?
///
/// *NOTE* this does *not* read the electrical state of the pin
fn is_set_low(&self) -> bool;
fn is_set_low(&self) -> Result<bool, Self::Error>;
}

/// Output pin that can be toggled
Expand All @@ -41,48 +44,55 @@ pub trait StatefulOutputPin {
/// implemented. Otherwise, implement this using hardware mechanisms.
#[cfg(feature = "unproven")]
pub trait ToggleableOutputPin {
/// Error type
type Error;

/// Toggle pin output.
fn toggle(&mut self);
fn toggle(&mut self) -> Result<(), Self::Error>;
}

/// If you can read **and** write the output state, a pin is
/// toggleable by software.
///
/// ```
/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
/// use embedded_hal::digital::toggleable;
/// use embedded_hal::digital::v2::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
/// use embedded_hal::digital::v2::toggleable;
///
/// /// A virtual output pin that exists purely in software
/// struct MyPin {
/// state: bool
/// }
///
/// impl OutputPin for MyPin {
/// fn set_low(&mut self) {
/// type Error = void::Void;
///
/// fn set_low(&mut self) -> Result<(), Self::Error> {
/// self.state = false;
/// Ok(())
/// }
/// fn set_high(&mut self) {
/// fn set_high(&mut self) -> Result<(), Self::Error> {
/// self.state = true;
/// Ok(())
/// }
/// }
///
/// impl StatefulOutputPin for MyPin {
/// fn is_set_low(&self) -> bool {
/// !self.state
/// fn is_set_low(&self) -> Result<bool, Self::Error> {
/// Ok(!self.state)
/// }
/// fn is_set_high(&self) -> bool {
/// self.state
/// fn is_set_high(&self) -> Result<bool, Self::Error> {
/// Ok(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());
/// pin.toggle().unwrap();
/// assert!(pin.is_set_high().unwrap());
/// pin.toggle().unwrap();
/// assert!(pin.is_set_low().unwrap());
/// ```
#[cfg(feature = "unproven")]
pub mod toggleable {
Expand All @@ -97,12 +107,14 @@ pub mod toggleable {
where
P: Default,
{
type Error = P::Error;

/// Toggle pin output
fn toggle(&mut self) {
if self.is_set_low() {
self.set_high();
fn toggle(&mut self) -> Result<(), Self::Error> {
if self.is_set_low()? {
self.set_high()
} else {
self.set_low();
self.set_low()
}
}
}
Expand All @@ -113,9 +125,12 @@ pub mod toggleable {
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
#[cfg(feature = "unproven")]
pub trait InputPin {
/// Error type
type Error;

/// Is the input pin high?
fn is_high(&self) -> bool;
fn is_high(&self) -> Result<bool, Self::Error>;

/// Is the input pin low?
fn is_low(&self) -> bool;
fn is_low(&self) -> Result<bool, Self::Error>;
}
3 changes: 3 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ pub use blocking::serial::Write as _embedded_hal_blocking_serial_Write;
pub use blocking::spi::{
Transfer as _embedded_hal_blocking_spi_Transfer, Write as _embedded_hal_blocking_spi_Write,
};
#[allow(deprecated)]
#[cfg(feature = "unproven")]
pub use digital::InputPin as _embedded_hal_digital_InputPin;
#[allow(deprecated)]
pub use digital::OutputPin as _embedded_hal_digital_OutputPin;
#[cfg(feature = "unproven")]
#[allow(deprecated)]
pub use digital::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPin;
pub use serial::Read as _embedded_hal_serial_Read;
pub use serial::Write as _embedded_hal_serial_Write;
Expand Down