Skip to content

Remove the various Default traits #289

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

Merged
merged 2 commits into from
Jul 20, 2021
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
importing the `nb` crate directly in dependendent crates.
- `blocking::Serial`: renamed `bwrite_all` to `write`, `bflush` to `flush.
- Removed `prelude` to avoid method name conflicts between different flavors (blocking, nb) of the same trait. Traits must now be manually imported.
- Removed the various `Default` marker traits.

## [v1.0.0-alpha.4] - 2020-11-11

Expand Down
67 changes: 0 additions & 67 deletions src/blocking/digital.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,73 +96,6 @@ pub trait ToggleableOutputPin {
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::blocking::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
/// use embedded_hal::blocking::digital::toggleable;
/// use core::convert::Infallible;
///
/// /// A virtual output pin that exists purely in software
/// struct MyPin {
/// state: bool
/// }
///
/// impl OutputPin for MyPin {
/// type Error = Infallible;
///
/// fn set_low(&mut self) -> Result<(), Self::Error> {
/// self.state = false;
/// Ok(())
/// }
/// fn set_high(&mut self) -> Result<(), Self::Error> {
/// self.state = true;
/// Ok(())
/// }
/// }
///
/// impl StatefulOutputPin for MyPin {
/// fn is_set_low(&self) -> Result<bool, Self::Error> {
/// Ok(!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().unwrap();
/// assert!(pin.is_set_high().unwrap());
/// pin.toggle().unwrap();
/// assert!(pin.is_set_low().unwrap());
/// ```
pub mod toggleable {
use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin};

/// Software-driven `toggle()` implementation.
pub trait Default: OutputPin + StatefulOutputPin {}

impl<P> ToggleableOutputPin for P
where
P: Default,
{
type Error = P::Error;

/// Toggle pin output
fn toggle(&mut self) -> Result<(), Self::Error> {
if self.is_set_low()? {
self.set_high()
} else {
self.set_low()
}
}
}
}

/// Single digital input pin
pub trait InputPin {
/// Error type
Expand Down
85 changes: 0 additions & 85 deletions src/blocking/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,88 +292,3 @@ pub trait TransactionalIter<A: AddressMode = SevenBitAddress> {
where
O: IntoIterator<Item = Operation<'a>>;
}

/// Default implementation of `blocking::i2c::Write`, `blocking::i2c::Read` and
/// `blocking::i2c::WriteRead` traits for `blocking::i2c::Transactional` implementers.
///
/// If you implement `blocking::i2c::Transactional` for your I2C peripheral,
/// you can use this default implementation so that you do not need to implement
/// the `blocking::i2c::Write`, `blocking::i2c::Read` and `blocking::i2c::WriteRead`
/// traits as well.
/// ```
/// use embedded_hal::blocking::i2c;
///
/// struct I2c1;
///
/// impl i2c::Transactional<i2c::SevenBitAddress> for I2c1 {
/// # type Error = ();
/// fn exec<'a>(
/// &mut self,
/// address: i2c::SevenBitAddress,
/// operations: &mut [i2c::Operation<'a>],
/// ) -> Result<(), Self::Error> {
/// // ...
/// # Ok(())
/// }
/// }
///
/// // This is all you need to do:
/// impl i2c::transactional::Default<i2c::SevenBitAddress> for I2c1 {};
///
/// // Then you can use `Write` and so on:
/// use i2c::Write;
///
/// let mut i2c1 = I2c1{};
/// i2c1.write(0x01, &[0xAB, 0xCD]).unwrap();
/// ```
pub mod transactional {
use super::{AddressMode, Operation, Read, Transactional, Write, WriteRead};

/// Default implementation of `blocking::i2c::Write`, `blocking::i2c::Read` and
/// `blocking::i2c::WriteRead` traits for `blocking::i2c::Transactional` implementers.
pub trait Default<A: AddressMode>: Transactional<A> {}

impl<A, E, S> Write<A> for S
where
A: AddressMode,
S: self::Default<A> + Transactional<A, Error = E>,
{
type Error = E;

fn write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error> {
self.exec(address, &mut [Operation::Write(bytes)])
}
}

impl<A, E, S> Read<A> for S
where
A: AddressMode,
S: self::Default<A> + Transactional<A, Error = E>,
{
type Error = E;

fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.exec(address, &mut [Operation::Read(buffer)])
}
}

impl<A, E, S> WriteRead<A> for S
where
A: AddressMode,
S: self::Default<A> + Transactional<A, Error = E>,
{
type Error = E;

fn write_read(
&mut self,
address: A,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.exec(
address,
&mut [Operation::Write(bytes), Operation::Read(buffer)],
)
}
}
}
34 changes: 0 additions & 34 deletions src/blocking/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,3 @@ pub trait Write<Word> {
/// Block until the serial interface has sent all buffered words
fn flush(&mut self) -> Result<(), Self::Error>;
}

/// Blocking serial write
pub mod write {
/// Marker trait to opt into default blocking write implementation
///
/// Implementers of [`nonblocking::serial::Write`] can implement this marker trait
/// for their type. Doing so will automatically provide the default
/// implementation of [`blocking::serial::Write`] for the type.
///
/// [`nonblocking::serial::Write`]: ../../nonblocking/serial/trait.Write.html
/// [`blocking::serial::Write`]: ../trait.Write.html
pub trait Default<Word>: crate::nb::serial::Write<Word> {}

impl<S, Word> crate::blocking::serial::Write<Word> for S
where
S: Default<Word>,
Word: Clone,
{
type Error = S::Error;

fn write(&mut self, buffer: &[Word]) -> Result<(), Self::Error> {
for word in buffer {
nb::block!(self.write(word.clone()))?;
}

Ok(())
}

fn flush(&mut self) -> Result<(), Self::Error> {
nb::block!(self.flush())?;
Ok(())
}
}
}
103 changes: 0 additions & 103 deletions src/blocking/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,81 +29,6 @@ pub trait WriteIter<W> {
WI: IntoIterator<Item = W>;
}

/// Blocking transfer
pub mod transfer {
/// Default implementation of `blocking::spi::Transfer<W>` for implementers of
/// `nonblocking::spi::FullDuplex<W>`
pub trait Default<W>: crate::nb::spi::FullDuplex<W> {}

impl<W, S> crate::blocking::spi::Transfer<W> for S
where
S: Default<W>,
W: Clone,
{
type Error = S::Error;

fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> {
for word in words.iter_mut() {
nb::block!(self.write(word.clone()))?;
*word = nb::block!(self.read())?;
}

Ok(words)
}
}
}

/// Blocking write
pub mod write {
/// Default implementation of `blocking::spi::Write<W>` for implementers
/// of `nonblocking::spi::FullDuplex<W>`
pub trait Default<W>: crate::nb::spi::FullDuplex<W> {}

impl<W, S> crate::blocking::spi::Write<W> for S
where
S: Default<W>,
W: Clone,
{
type Error = S::Error;

fn write(&mut self, words: &[W]) -> Result<(), S::Error> {
for word in words {
nb::block!(self.write(word.clone()))?;
nb::block!(self.read())?;
}

Ok(())
}
}
}

/// Blocking write (iterator version)
pub mod write_iter {
/// Default implementation of `blocking::spi::WriteIter<W>` for implementers of
/// `nonblocking::spi::FullDuplex<W>`
pub trait Default<W>: crate::nb::spi::FullDuplex<W> {}

impl<W, S> crate::blocking::spi::WriteIter<W> for S
where
S: Default<W>,
W: Clone,
{
type Error = S::Error;

fn write_iter<WI>(&mut self, words: WI) -> Result<(), S::Error>
where
WI: IntoIterator<Item = W>,
{
for word in words.into_iter() {
nb::block!(self.write(word.clone()))?;
nb::block!(self.read())?;
}

Ok(())
}
}
}

/// Operation for transactional SPI trait
///
/// This allows composition of SPI operations into a single bus transaction
Expand All @@ -124,31 +49,3 @@ pub trait Transactional<W: 'static> {
/// Execute the provided transactions
fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error>;
}

/// Blocking transactional impl over spi::Write and spi::Transfer
pub mod transactional {
use super::{Operation, Transfer, Write};

/// Default implementation of `blocking::spi::Transactional<W>` for implementers of
/// `spi::Write<W>` and `spi::Transfer<W>`
pub trait Default<W>: Write<W> + Transfer<W> {}

impl<W: 'static, E, S> super::Transactional<W> for S
where
S: self::Default<W> + Write<W, Error = E> + Transfer<W, Error = E>,
W: Copy + Clone,
{
type Error = E;

fn exec<'a>(&mut self, operations: &mut [super::Operation<'a, W>]) -> Result<(), E> {
for op in operations {
match op {
Operation::Write(w) => self.write(w)?,
Operation::Transfer(t) => self.transfer(t).map(|_| ())?,
}
}

Ok(())
}
}
}