diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c9a13ab0f..fcca011ea 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @rust-embedded/hal @ilya-epifanov @thejpster +* @rust-embedded/hal diff --git a/.github/bors.toml b/.github/bors.toml index ca42be0a5..c646f2461 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -1,4 +1,10 @@ block_labels = ["needs-decision"] delete_merged_branches = true required_approvals = 1 -status = ["continuous-integration/travis-ci/push"] +status = [ + "ci-linux (stable, x86_64-unknown-linux-gnu)", + "ci-linux (stable, thumbv6m-none-eabi)", + "ci-linux (stable, thumbv7m-none-eabi)", + "ci-linux (1.31.0, x86_64-unknown-linux-gnu)", + "fmt", +] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..1df8088de --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,48 @@ +on: + push: + branches: [ staging, trying, master ] + pull_request: + +name: Continuous integration + +env: + RUSTFLAGS: '--deny warnings' + +jobs: + ci-linux: + runs-on: ubuntu-latest + strategy: + matrix: + # All generated code should be running on stable now + rust: [stable] + + # The default target we're compiling on and for + TARGET: [x86_64-unknown-linux-gnu, thumbv6m-none-eabi, thumbv7m-none-eabi] + + include: + - rust: 1.31.0 + TARGET: x86_64-unknown-linux-gnu + + # Test nightly but don't fail + - rust: nightly + experimental: true + TARGET: x86_64-unknown-linux-gnu + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.TARGET }} + override: true + - uses: actions-rs/cargo@v1 + with: + command: check + args: --target=${{ matrix.TARGET }} + + - uses: actions-rs/cargo@v1 + with: + command: check + args: --target=${{ matrix.TARGET }} --features unproven + diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml new file mode 100644 index 000000000..adc3a6ed1 --- /dev/null +++ b/.github/workflows/clippy.yml @@ -0,0 +1,20 @@ +on: + push: + branches: [ staging, trying, master ] + pull_request: + +name: Clippy check +jobs: + clippy_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: clippy + - uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/rustfmt.yml b/.github/workflows/rustfmt.yml new file mode 100644 index 000000000..80439edbd --- /dev/null +++ b/.github/workflows/rustfmt.yml @@ -0,0 +1,22 @@ +on: + push: + branches: [ staging, trying, master ] + pull_request: + +name: Code formatting check + +jobs: + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..ff46d17df --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,29 @@ +on: + push: + branches: [ staging, trying, master ] + pull_request: + +name: Test Suite + +env: + RUSTFLAGS: '--deny warnings' + +jobs: + ci-linux: + runs-on: ubuntu-latest + strategy: + matrix: + rust: [nightly] + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.TARGET }} + override: true + - uses: actions-rs/cargo@v1 + with: + command: test + args: --features unproven diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index be4e5a45d..000000000 --- a/.travis.yml +++ /dev/null @@ -1,50 +0,0 @@ -language: rust - -env: - global: - RUSTFLAGS='-D warnings' - -matrix: - include: - - env: TARGET=x86_64-unknown-linux-gnu - if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master) - - - env: TARGET=thumbv6m-none-eabi - rust: beta - if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master) - - - env: TARGET=thumbv7m-none-eabi - rust: beta - if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master) - - - env: TARGET=x86_64-unknown-linux-gnu - rust: nightly - if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master) - -before_install: set -e - -install: - - bash ci/install.sh - -script: - - bash ci/script.sh - -after_script: set +e - -after_success: - - bash ci/after_success.sh - -cache: cargo -before_cache: - # Travis can't cache files that are not readable by "others" - - chmod -R a+r $HOME/.cargo - -branches: - only: - - master - - staging - - trying - -notifications: - email: - on_success: never diff --git a/ci/after_success.sh b/ci/after_success.sh deleted file mode 100644 index c44255907..000000000 --- a/ci/after_success.sh +++ /dev/null @@ -1,20 +0,0 @@ -set -euxo pipefail - -main() { - cargo doc --target $TARGET - - mkdir ghp-import - - curl -Ls https://github.com/davisp/ghp-import/archive/master.tar.gz | \ - tar --strip-components 1 -C ghp-import -xz - - ./ghp-import/ghp_import.py target/$TARGET/doc - - set +x - git push -fq https://$GH_TOKEN@github.com/$TRAVIS_REPO_SLUG.git gh-pages && \ - echo OK -} - -if [ "$TRAVIS_EVENT_TYPE" == "push" ] && [ "$TRAVIS_BRANCH" == "master" ]; then - main -fi diff --git a/ci/install.sh b/ci/install.sh deleted file mode 100644 index 3c4192119..000000000 --- a/ci/install.sh +++ /dev/null @@ -1,9 +0,0 @@ -set -euxo pipefail - -main() { - if [ $TARGET != x86_64-unknown-linux-gnu ]; then - rustup target add $TARGET - fi -} - -main diff --git a/ci/script.sh b/ci/script.sh deleted file mode 100644 index 12c05e27b..000000000 --- a/ci/script.sh +++ /dev/null @@ -1,12 +0,0 @@ -set -euxo pipefail - -main() { - cargo check --target $TARGET - cargo check --target $TARGET --features unproven - - if [ $TRAVIS_RUST_VERSION = nightly ]; then - cargo test --target $TARGET --features unproven - fi -} - -main diff --git a/src/blocking/i2c.rs b/src/blocking/i2c.rs index 1c654f770..57192cac8 100644 --- a/src/blocking/i2c.rs +++ b/src/blocking/i2c.rs @@ -124,6 +124,6 @@ pub trait WriteIterRead { bytes: B, buffer: &mut [u8], ) -> Result<(), Self::Error> - where + where B: IntoIterator; } diff --git a/src/digital/mod.rs b/src/digital/mod.rs index 4e67f9851..5e1848f02 100644 --- a/src/digital/mod.rs +++ b/src/digital/mod.rs @@ -1,11 +1,14 @@ //! Digital I/O //! -//! +//! //! // Deprecated / infallible traits -#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \ - Users should use the traits in digital::v2.")] +#[deprecated( + since = "0.2.2", + note = "Deprecated because the methods cannot return errors. \ + Users should use the traits in digital::v2." +)] pub mod v1; // New / fallible traits @@ -22,4 +25,3 @@ pub mod v2_compat; // Re-export old traits so this isn't a breaking change #[allow(deprecated)] pub use self::v1::*; - diff --git a/src/digital/v1_compat.rs b/src/digital/v1_compat.rs index bb3430f58..83a9ffce7 100644 --- a/src/digital/v1_compat.rs +++ b/src/digital/v1_compat.rs @@ -34,7 +34,6 @@ //! ``` //! - #[allow(deprecated)] use super::v1; use super::v2; @@ -44,14 +43,14 @@ pub struct OldOutputPin { pin: T, } -impl OldOutputPin +impl OldOutputPin where - T: v2::OutputPin, + T: v2::OutputPin, E: core::fmt::Debug, { /// Create a new OldOutputPin wrapper around a `v2::OutputPin` pub fn new(pin: T) -> Self { - Self{pin} + Self { pin } } /// Fetch a reference to the inner `v2::OutputPin` impl @@ -61,22 +60,22 @@ where } } -impl From for OldOutputPin +impl From for OldOutputPin where - T: v2::OutputPin, + T: v2::OutputPin, E: core::fmt::Debug, { fn from(pin: T) -> Self { - OldOutputPin{pin} + OldOutputPin { pin } } } /// Implementation of `v1::OutputPin` trait for fallible `v2::OutputPin` output pins /// where errors will panic. #[allow(deprecated)] -impl v1::OutputPin for OldOutputPin +impl v1::OutputPin for OldOutputPin where - T: v2::OutputPin, + T: v2::OutputPin, E: core::fmt::Debug, { fn set_low(&mut self) { @@ -92,9 +91,9 @@ where /// where errors will panic. #[cfg(feature = "unproven")] #[allow(deprecated)] -impl v1::StatefulOutputPin for OldOutputPin +impl v1::StatefulOutputPin for OldOutputPin where - T: v2::StatefulOutputPin, + T: v2::StatefulOutputPin, E: core::fmt::Debug, { fn is_set_low(&self) -> bool { @@ -114,26 +113,25 @@ pub struct OldInputPin { } #[cfg(feature = "unproven")] -impl OldInputPin +impl OldInputPin where - T: v2::InputPin, + T: v2::InputPin, E: core::fmt::Debug, { /// Create an `OldInputPin` wrapper around a `v2::InputPin`. pub fn new(pin: T) -> Self { - Self{pin} + Self { pin } } - } #[cfg(feature = "unproven")] -impl From for OldInputPin +impl From for OldInputPin where - T: v2::InputPin, + T: v2::InputPin, E: core::fmt::Debug, { fn from(pin: T) -> Self { - OldInputPin{pin} + OldInputPin { pin } } } @@ -141,9 +139,9 @@ where /// where errors will panic. #[cfg(feature = "unproven")] #[allow(deprecated)] -impl v1::InputPin for OldInputPin +impl v1::InputPin for OldInputPin where - T: v2::InputPin, + T: v2::InputPin, E: core::fmt::Debug, { fn is_low(&self) -> bool { @@ -169,7 +167,7 @@ mod tests { #[derive(Clone)] struct NewOutputPinImpl { state: bool, - res: Result<(), ()> + res: Result<(), ()>, } impl v2::OutputPin for NewOutputPinImpl { @@ -179,7 +177,7 @@ mod tests { self.state = false; self.res } - fn set_high(&mut self) -> Result<(), Self::Error>{ + fn set_high(&mut self) -> Result<(), Self::Error> { self.state = true; self.res } @@ -191,23 +189,31 @@ mod tests { } #[allow(deprecated)] - impl OldOutputPinConsumer - where T: v1::OutputPin + impl OldOutputPinConsumer + where + T: v1::OutputPin, { pub fn new(pin: T) -> OldOutputPinConsumer { - OldOutputPinConsumer{ _pin: pin } + OldOutputPinConsumer { _pin: pin } } } #[test] fn v1_v2_output_explicit() { - let i = NewOutputPinImpl{state: false, res: Ok(())}; + let i = NewOutputPinImpl { + state: false, + res: Ok(()), + }; let _c: OldOutputPinConsumer> = OldOutputPinConsumer::new(i.into()); } #[test] fn v1_v2_output_state() { - let mut o: OldOutputPin<_> = NewOutputPinImpl{state: false, res: Ok(())}.into(); + let mut o: OldOutputPin<_> = NewOutputPinImpl { + state: false, + res: Ok(()), + } + .into(); o.set_high(); assert_eq!(o.inner().state, true); @@ -219,7 +225,11 @@ mod tests { #[test] #[should_panic] fn v1_v2_output_panic() { - let mut o: OldOutputPin<_> = NewOutputPinImpl{state: false, res: Err(())}.into(); + let mut o: OldOutputPin<_> = NewOutputPinImpl { + state: false, + res: Err(()), + } + .into(); o.set_high(); } @@ -239,7 +249,7 @@ mod tests { fn is_low(&self) -> Result { self.state.map(|v| v == false) } - fn is_high(&self) -> Result{ + fn is_high(&self) -> Result { self.state.map(|v| v == true) } } @@ -252,25 +262,26 @@ mod tests { #[cfg(feature = "unproven")] #[allow(deprecated)] - impl OldInputPinConsumer - where T: v1::InputPin + impl OldInputPinConsumer + where + T: v1::InputPin, { pub fn new(pin: T) -> OldInputPinConsumer { - OldInputPinConsumer{ _pin: pin } + OldInputPinConsumer { _pin: pin } } } #[cfg(feature = "unproven")] #[test] fn v1_v2_input_explicit() { - let i = NewInputPinImpl{state: Ok(false)}; + let i = NewInputPinImpl { state: Ok(false) }; let _c: OldInputPinConsumer> = OldInputPinConsumer::new(i.into()); } #[cfg(feature = "unproven")] #[test] fn v1_v2_input_state() { - let i: OldInputPin<_> = NewInputPinImpl{state: Ok(false)}.into(); + let i: OldInputPin<_> = NewInputPinImpl { state: Ok(false) }.into(); assert_eq!(i.is_low(), true); assert_eq!(i.is_high(), false); @@ -280,9 +291,8 @@ mod tests { #[test] #[should_panic] fn v1_v2_input_panic() { - let i: OldInputPin<_> = NewInputPinImpl{state: Err(())}.into(); + let i: OldInputPin<_> = NewInputPinImpl { state: Err(()) }.into(); i.is_low(); } - } diff --git a/src/digital/v2.rs b/src/digital/v2.rs index 748807225..d539606fb 100644 --- a/src/digital/v2.rs +++ b/src/digital/v2.rs @@ -24,7 +24,7 @@ pub trait OutputPin { /// /// *This trait is available if embedded-hal is built with the `"unproven"` feature.* #[cfg(feature = "unproven")] -pub trait StatefulOutputPin : OutputPin { +pub trait StatefulOutputPin: OutputPin { /// Is the pin in drive high mode? /// /// *NOTE* this does *not* read the electrical state of the pin diff --git a/src/digital/v2_compat.rs b/src/digital/v2_compat.rs index c96fee8b3..9c87271c8 100644 --- a/src/digital/v2_compat.rs +++ b/src/digital/v2_compat.rs @@ -1,36 +1,36 @@ //! v2 compatibility shims -//! +//! //! 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 { //! _pin: T, //! } -//! -//! impl NewOutputPinConsumer +//! +//! impl NewOutputPinConsumer //! where T: v2::OutputPin { //! pub fn new(pin: T) -> NewOutputPinConsumer { //! NewOutputPinConsumer{ _pin: pin } //! } //! } -//! +//! //! fn main() { //! let pin = OldOutputPinImpl{}; //! let _consumer = NewOutputPinConsumer::new(pin); //! } //! ``` -//! +//! #[allow(deprecated)] use super::v1; @@ -38,7 +38,7 @@ use super::v2; /// Implementation of fallible `v2::OutputPin` for `v1::OutputPin` traits #[allow(deprecated)] -impl v2::OutputPin for T +impl v2::OutputPin for T where T: v1::OutputPin, { @@ -50,14 +50,14 @@ where } fn set_high(&mut self) -> Result<(), Self::Error> { - Ok(self.set_high()) - } + Ok(self.set_high()) + } } /// Implementation of fallible `v2::StatefulOutputPin` for `v1::StatefulOutputPin` digital traits #[cfg(feature = "unproven")] #[allow(deprecated)] -impl v2::StatefulOutputPin for T +impl v2::StatefulOutputPin for T where T: v1::StatefulOutputPin + v1::OutputPin, { @@ -65,9 +65,9 @@ where Ok(self.is_set_low()) } - fn is_set_high(&self) -> Result { - Ok(self.is_set_high()) - } + fn is_set_high(&self) -> Result { + Ok(self.is_set_high()) + } } #[cfg(feature = "unproven")] @@ -77,9 +77,9 @@ impl v2::toggleable::Default for T where T: v1::toggleable::Default {} /// Implementation of fallible `v2::InputPin` for `v1::InputPin` digital traits #[cfg(feature = "unproven")] #[allow(deprecated)] -impl v2::InputPin for T +impl v2::InputPin for T where - T: v1::InputPin + T: v1::InputPin, { // TODO: update to ! when never_type is stabilized type Error = (); @@ -88,9 +88,9 @@ where Ok(self.is_low()) } - fn is_high(&self) -> Result { - Ok(self.is_high()) - } + fn is_high(&self) -> Result { + Ok(self.is_high()) + } } #[cfg(test)] @@ -101,8 +101,8 @@ mod tests { use crate::digital::v2; #[allow(deprecated)] - struct OldOutputPinImpl { - state: bool + struct OldOutputPinImpl { + state: bool, } #[allow(deprecated)] @@ -133,10 +133,12 @@ mod tests { _pin: T, } - impl NewOutputPinConsumer - where T: v2::OutputPin { + impl NewOutputPinConsumer + where + T: v2::OutputPin, + { pub fn new(pin: T) -> NewOutputPinConsumer { - NewOutputPinConsumer{ _pin: pin } + NewOutputPinConsumer { _pin: pin } } } @@ -161,14 +163,14 @@ mod tests { #[test] fn v2_v1_output_implicit() { - let i = OldOutputPinImpl{state: false}; + let i = OldOutputPinImpl { state: false }; let _c = NewOutputPinConsumer::new(i); } #[test] fn v2_v1_output_state() { - let mut o = OldOutputPinImpl{state: false}; - + let mut o = OldOutputPinImpl { state: false }; + v2::OutputPin::set_high(&mut o).unwrap(); assert_eq!(o.state, true); @@ -178,8 +180,8 @@ mod tests { #[cfg(feature = "unproven")] #[allow(deprecated)] - struct OldInputPinImpl { - state: bool + struct OldInputPinImpl { + state: bool, } #[cfg(feature = "unproven")] @@ -199,26 +201,28 @@ mod tests { } #[cfg(feature = "unproven")] - impl NewInputPinConsumer - where T: v2::InputPin { + impl NewInputPinConsumer + where + T: v2::InputPin, + { pub fn new(pin: T) -> NewInputPinConsumer { - NewInputPinConsumer{ _pin: pin } + NewInputPinConsumer { _pin: pin } } } #[cfg(feature = "unproven")] #[test] fn v2_v1_input_implicit() { - let i = OldInputPinImpl{state: false}; + let i = OldInputPinImpl { state: false }; let _c = NewInputPinConsumer::new(i); } #[cfg(feature = "unproven")] #[test] fn v2_v1_input_state() { - let mut i = OldInputPinImpl{state: false}; - + let mut i = OldInputPinImpl { state: false }; + assert_eq!(v2::InputPin::is_high(&mut i).unwrap(), false); assert_eq!(v2::InputPin::is_low(&mut i).unwrap(), true); } -} \ No newline at end of file +} diff --git a/src/fmt.rs b/src/fmt.rs index d9d0446c0..33041a84f 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -3,12 +3,13 @@ //! TODO write example of usage use core::fmt::{Result, Write}; -impl Write for dyn (::serial::Write) +impl Write for dyn (::serial::Write) where Word: From, { fn write_str(&mut self, s: &str) -> Result { - let _ = s.as_bytes() + let _ = s + .as_bytes() .into_iter() .map(|c| block!(self.write(Word::from(*c)))) .last(); diff --git a/src/lib.rs b/src/lib.rs index 5e07ec736..be6c954b0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -439,8 +439,8 @@ //! //! // Event loop //! loop { -//! Pin::new(&mut blinky).resume(); -//! Pin::new(&mut loopback).resume(); +//! Pin::new(&mut blinky).resume(()); +//! Pin::new(&mut loopback).resume(()); //! # break; //! } //! } diff --git a/src/spi.rs b/src/spi.rs index b91e6d68b..20d8538cd 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -75,4 +75,4 @@ pub const MODE_2: Mode = Mode { pub const MODE_3: Mode = Mode { polarity: Polarity::IdleHigh, phase: Phase::CaptureOnSecondTransition, -}; \ No newline at end of file +}; diff --git a/src/timer.rs b/src/timer.rs index 74cf088f3..08ba27606 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -81,7 +81,7 @@ pub trait CountDown { pub trait Periodic {} /// Trait for cancelable countdowns. -pub trait Cancel : CountDown { +pub trait Cancel: CountDown { /// Error returned when a countdown can't be canceled. type Error; diff --git a/src/watchdog.rs b/src/watchdog.rs index ee8cefc32..41e76f6ba 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -1,7 +1,5 @@ //! Traits for interactions with a processors watchdog timer. - - /// Feeds an existing watchdog to ensure the processor isn't reset. Sometimes /// commonly referred to as "kicking" or "refreshing". #[cfg(feature = "unproven")] @@ -11,19 +9,19 @@ pub trait Watchdog { fn feed(&mut self); } - -/// Enables A watchdog timer to reset the processor if software is frozen or +/// Enables A watchdog timer to reset the processor if software is frozen or /// stalled. #[cfg(feature = "unproven")] pub trait WatchdogEnable { /// Unit of time used by the watchdog type Time; - /// Starts the watchdog with a given period, typically once this is done - /// the watchdog needs to be kicked periodically or the processor is reset. - fn start(&mut self, period: T) where T: Into; + /// Starts the watchdog with a given period, typically once this is done + /// the watchdog needs to be kicked periodically or the processor is reset. + fn start(&mut self, period: T) + where + T: Into; } - /// Disables a running watchdog timer so the processor won't be reset. #[cfg(feature = "unproven")] pub trait WatchdogDisable {