Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 264d080

Browse files
bors[bot]ryankurteeldruintherealprof
committedMar 21, 2019
Merge #127
127: Digital v1 <-> v2 compatibility wrappers and shims r=japaric a=ryankurte This PR introduces implicit v1 -> v2 (forward) compatibility, and explicit wrapper types for v2 -> v1 (reverse) compatibility between digital trait versions as a final step for #95, as well as moving the deprecated v1 traits to a re-exported module for clarity. As @japaric pointed out, it is not feasible to have implicit compatibility in both directions, so it seemed reasonable to make regression explicit as it hides an `.unwrap()` on failure. @therealprof, @hannobraun, @eldruin what do you think of this approach? I think it probably needs more documentation, though I am definitely open to suggestions as to what / where. See also: #100, #92, #102. Co-authored-by: Ryan Kurte <ryankurte@gmail.com> Co-authored-by: Diego Barrios Romero <eldruin@gmail.com> Co-authored-by: Daniel Egger <daniel@eggers-club.de>
2 parents 8d2ca00 + dbf815c commit 264d080

File tree

6 files changed

+578
-146
lines changed

6 files changed

+578
-146
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1313
fallible and their methods now return a `Result` type as setting an output pin
1414
and reading an input pin could potentially fail.
1515
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.
16+
- Compatibility shims between `digital::v1` and `digital::v2` traits allowing v1 traits
17+
to be implicitly promoted to v2, and for v2 traits to be explicitly cast to v1 wrappers.
1618

1719
### Changed
1820
- The current versions of the `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`

‎src/digital/mod.rs

+15-145
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,25 @@
11
//! Digital I/O
22
//!
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-
}
3+
//!
4+
//!
655
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-
/// ```
6+
// Deprecated / infallible traits
1087
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
1098
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};
9+
pub mod v1;
11410

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 {}
11+
// New / fallible traits
12+
pub mod v2;
12013

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-
}
14+
// v2 -> v1 compatibility wrappers
15+
// These require explicit casts from v2 -> v1
16+
pub mod v1_compat;
13617

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;
18+
// v1 -> v2 compatibility shims
19+
// These are implicit over v1 implementations
20+
pub mod v2_compat;
14921

150-
/// Is the input pin low?
151-
fn is_low(&self) -> bool;
152-
}
22+
// Re-export old traits so this isn't a breaking change
23+
#[allow(deprecated)]
24+
pub use self::v1::*;
15325

154-
/// Improved version of the digital traits where the methods can also return an error.
155-
pub mod v2;

‎src/digital/v1.rs

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

0 commit comments

Comments
 (0)
Failed to load comments.