Skip to content

Commit d8c78cc

Browse files
bors[bot]eldruinryankurte
committed
Merge #108
108: Add fallible version of the digital traits and deprecate the current ones r=ryankurte a=eldruin There seems to be an agreement in [#100](#100 (comment)) on how to proceed with the fallible traits. This adds the fallible traits under `digital::v2` and marks the current ones as deprecated. Co-authored-by: Diego Barrios Romero <[email protected]> Co-authored-by: Ryan <[email protected]>
2 parents 02f1842 + 14cac99 commit d8c78cc

File tree

4 files changed

+213
-25
lines changed

4 files changed

+213
-25
lines changed

CHANGELOG.md

+15
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
- A new version of the digital `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
12+
and `InputPin` traits has been added under `digital::v2`. These traits are now
13+
fallible and their methods now return a `Result` type as setting an output pin
14+
and reading an input pin could potentially fail.
15+
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.
16+
17+
### Changed
18+
- The current versions of the `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
19+
and `InputPin` traits have been marked as deprecated. Please use the new versions
20+
included in `digital::v2`.
21+
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.
22+
23+
1024
## [v0.2.2] - 2018-11-03
1125

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

38+
2439
## [v0.2.1] - 2018-05-14
2540

2641
### Changed

src/digital/mod.rs

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
//! Digital I/O
2+
//!
3+
//! The traits in this module are now deprecated. Please use the new versions included
4+
//! in `digital::v2`.
5+
6+
/// Single digital push-pull output pin
7+
///
8+
/// *This version of the trait is now deprecated. Please use the new `OutputPin` trait in
9+
/// `digital::v2::OutputPin`*.
10+
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
11+
Users should use the traits in digital::v2.")]
12+
pub trait OutputPin {
13+
/// Drives the pin low
14+
///
15+
/// *NOTE* the actual electrical state of the pin may not actually be low, e.g. due to external
16+
/// electrical sources
17+
fn set_low(&mut self);
18+
19+
/// Drives the pin high
20+
///
21+
/// *NOTE* the actual electrical state of the pin may not actually be high, e.g. due to external
22+
/// electrical sources
23+
fn set_high(&mut self);
24+
}
25+
26+
/// Push-pull output pin that can read its output state
27+
///
28+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
29+
///
30+
/// *This version of the trait is now deprecated. Please use the new `StatefulOutputPin` trait in
31+
/// `digital::v2::StatefulOutputPin`*.
32+
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
33+
Users should use the traits in digital::v2.")]
34+
#[cfg(feature = "unproven")]
35+
pub trait StatefulOutputPin {
36+
/// Is the pin in drive high mode?
37+
///
38+
/// *NOTE* this does *not* read the electrical state of the pin
39+
fn is_set_high(&self) -> bool;
40+
41+
/// Is the pin in drive low mode?
42+
///
43+
/// *NOTE* this does *not* read the electrical state of the pin
44+
fn is_set_low(&self) -> bool;
45+
}
46+
47+
/// Output pin that can be toggled
48+
///
49+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
50+
///
51+
/// *This version of the trait is now deprecated. Please use the new `ToggleableOutputPin`
52+
/// trait in `digital::v2::ToggleableOutputPin`*.
53+
///
54+
/// See [toggleable](toggleable) to use a software implementation if
55+
/// both [OutputPin](trait.OutputPin.html) and
56+
/// [StatefulOutputPin](trait.StatefulOutputPin.html) are
57+
/// implemented. Otherwise, implement this using hardware mechanisms.
58+
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
59+
Users should use the traits in digital::v2.")]
60+
#[cfg(feature = "unproven")]
61+
pub trait ToggleableOutputPin {
62+
/// Toggle pin output.
63+
fn toggle(&mut self);
64+
}
65+
66+
/// If you can read **and** write the output state, a pin is
67+
/// toggleable by software.
68+
///
69+
/// *This version of the module is now deprecated. Please use the new `toggleable` module in
70+
/// `digital::v2::toggleable`*.
71+
///
72+
/// ```
73+
/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
74+
/// use embedded_hal::digital::toggleable;
75+
///
76+
/// /// A virtual output pin that exists purely in software
77+
/// struct MyPin {
78+
/// state: bool
79+
/// }
80+
///
81+
/// impl OutputPin for MyPin {
82+
/// fn set_low(&mut self) {
83+
/// self.state = false;
84+
/// }
85+
/// fn set_high(&mut self) {
86+
/// self.state = true;
87+
/// }
88+
/// }
89+
///
90+
/// impl StatefulOutputPin for MyPin {
91+
/// fn is_set_low(&self) -> bool {
92+
/// !self.state
93+
/// }
94+
/// fn is_set_high(&self) -> bool {
95+
/// self.state
96+
/// }
97+
/// }
98+
///
99+
/// /// Opt-in to the software implementation.
100+
/// impl toggleable::Default for MyPin {}
101+
///
102+
/// let mut pin = MyPin { state: false };
103+
/// pin.toggle();
104+
/// assert!(pin.is_set_high());
105+
/// pin.toggle();
106+
/// assert!(pin.is_set_low());
107+
/// ```
108+
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
109+
Users should use the traits in digital::v2.")]
110+
#[cfg(feature = "unproven")]
111+
pub mod toggleable {
112+
#[allow(deprecated)]
113+
use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
114+
115+
/// Software-driven `toggle()` implementation.
116+
///
117+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
118+
#[allow(deprecated)]
119+
pub trait Default: OutputPin + StatefulOutputPin {}
120+
121+
#[allow(deprecated)]
122+
impl<P> ToggleableOutputPin for P
123+
where
124+
P: Default,
125+
{
126+
/// Toggle pin output
127+
fn toggle(&mut self) {
128+
if self.is_set_low() {
129+
self.set_high();
130+
} else {
131+
self.set_low();
132+
}
133+
}
134+
}
135+
}
136+
137+
/// Single digital input pin
138+
///
139+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
140+
///
141+
/// *This version of the trait is now deprecated. Please use the new `InputPin` trait in
142+
/// `digital::v2::InputPin`*.
143+
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
144+
Users should use the traits in digital::v2.")]
145+
#[cfg(feature = "unproven")]
146+
pub trait InputPin {
147+
/// Is the input pin high?
148+
fn is_high(&self) -> bool;
149+
150+
/// Is the input pin low?
151+
fn is_low(&self) -> bool;
152+
}
153+
154+
/// Improved version of the digital traits where the methods can also return an error.
155+
pub mod v2;
+40-25
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1-
//! Digital I/O
1+
/// Digital I/O
22
33
/// Single digital push-pull output pin
44
pub trait OutputPin {
5+
/// Error type
6+
type Error;
7+
58
/// Drives the pin low
69
///
710
/// *NOTE* the actual electrical state of the pin may not actually be low, e.g. due to external
811
/// electrical sources
9-
fn set_low(&mut self);
12+
fn set_low(&mut self) -> Result<(), Self::Error>;
1013

1114
/// Drives the pin high
1215
///
1316
/// *NOTE* the actual electrical state of the pin may not actually be high, e.g. due to external
1417
/// electrical sources
15-
fn set_high(&mut self);
18+
fn set_high(&mut self) -> Result<(), Self::Error>;
1619
}
1720

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

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

3437
/// Output pin that can be toggled
@@ -41,48 +44,55 @@ pub trait StatefulOutputPin {
4144
/// implemented. Otherwise, implement this using hardware mechanisms.
4245
#[cfg(feature = "unproven")]
4346
pub trait ToggleableOutputPin {
47+
/// Error type
48+
type Error;
49+
4450
/// Toggle pin output.
45-
fn toggle(&mut self);
51+
fn toggle(&mut self) -> Result<(), Self::Error>;
4652
}
4753

4854
/// If you can read **and** write the output state, a pin is
4955
/// toggleable by software.
5056
///
5157
/// ```
52-
/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
53-
/// use embedded_hal::digital::toggleable;
58+
/// use embedded_hal::digital::v2::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
59+
/// use embedded_hal::digital::v2::toggleable;
5460
///
5561
/// /// A virtual output pin that exists purely in software
5662
/// struct MyPin {
5763
/// state: bool
5864
/// }
5965
///
6066
/// impl OutputPin for MyPin {
61-
/// fn set_low(&mut self) {
67+
/// type Error = void::Void;
68+
///
69+
/// fn set_low(&mut self) -> Result<(), Self::Error> {
6270
/// self.state = false;
71+
/// Ok(())
6372
/// }
64-
/// fn set_high(&mut self) {
73+
/// fn set_high(&mut self) -> Result<(), Self::Error> {
6574
/// self.state = true;
75+
/// Ok(())
6676
/// }
6777
/// }
6878
///
6979
/// impl StatefulOutputPin for MyPin {
70-
/// fn is_set_low(&self) -> bool {
71-
/// !self.state
80+
/// fn is_set_low(&self) -> Result<bool, Self::Error> {
81+
/// Ok(!self.state)
7282
/// }
73-
/// fn is_set_high(&self) -> bool {
74-
/// self.state
83+
/// fn is_set_high(&self) -> Result<bool, Self::Error> {
84+
/// Ok(self.state)
7585
/// }
7686
/// }
7787
///
7888
/// /// Opt-in to the software implementation.
7989
/// impl toggleable::Default for MyPin {}
8090
///
8191
/// let mut pin = MyPin { state: false };
82-
/// pin.toggle();
83-
/// assert!(pin.is_set_high());
84-
/// pin.toggle();
85-
/// assert!(pin.is_set_low());
92+
/// pin.toggle().unwrap();
93+
/// assert!(pin.is_set_high().unwrap());
94+
/// pin.toggle().unwrap();
95+
/// assert!(pin.is_set_low().unwrap());
8696
/// ```
8797
#[cfg(feature = "unproven")]
8898
pub mod toggleable {
@@ -97,12 +107,14 @@ pub mod toggleable {
97107
where
98108
P: Default,
99109
{
110+
type Error = P::Error;
111+
100112
/// Toggle pin output
101-
fn toggle(&mut self) {
102-
if self.is_set_low() {
103-
self.set_high();
113+
fn toggle(&mut self) -> Result<(), Self::Error> {
114+
if self.is_set_low()? {
115+
self.set_high()
104116
} else {
105-
self.set_low();
117+
self.set_low()
106118
}
107119
}
108120
}
@@ -113,9 +125,12 @@ pub mod toggleable {
113125
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
114126
#[cfg(feature = "unproven")]
115127
pub trait InputPin {
128+
/// Error type
129+
type Error;
130+
116131
/// Is the input pin high?
117-
fn is_high(&self) -> bool;
132+
fn is_high(&self) -> Result<bool, Self::Error>;
118133

119134
/// Is the input pin low?
120-
fn is_low(&self) -> bool;
135+
fn is_low(&self) -> Result<bool, Self::Error>;
121136
}

src/prelude.rs

+3
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ pub use blocking::serial::Write as _embedded_hal_blocking_serial_Write;
1515
pub use blocking::spi::{
1616
Transfer as _embedded_hal_blocking_spi_Transfer, Write as _embedded_hal_blocking_spi_Write,
1717
};
18+
#[allow(deprecated)]
1819
#[cfg(feature = "unproven")]
1920
pub use digital::InputPin as _embedded_hal_digital_InputPin;
21+
#[allow(deprecated)]
2022
pub use digital::OutputPin as _embedded_hal_digital_OutputPin;
2123
#[cfg(feature = "unproven")]
24+
#[allow(deprecated)]
2225
pub use digital::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPin;
2326
pub use serial::Read as _embedded_hal_serial_Read;
2427
pub use serial::Write as _embedded_hal_serial_Write;

0 commit comments

Comments
 (0)