mirror of
https://github.com/rust-embedded/embedded-hal.git
synced 2026-04-09 07:55:15 +00:00
async/spi: make helpers default methods instead of an extension trait.
It turns out you *can* have default methods on a GAT-based async trait. All you have to do is move the TAITs out of the trait so Rust infers them instead of the impl specifying them. Impls can't override the methods, but they already couldn't before with the extension trait. This makes async SpiDevice more consistent with blocking, and makes the helpers more discoverable.
This commit is contained in:
@@ -7,6 +7,34 @@ pub use embedded_hal::spi::{
|
||||
};
|
||||
use embedded_hal::{digital::blocking::OutputPin, spi::blocking};
|
||||
|
||||
type ReadFuture<'a, T, Word>
|
||||
where
|
||||
T: SpiDevice + ?Sized + 'a,
|
||||
T::Bus: SpiBusRead<Word>,
|
||||
Word: Copy + 'static,
|
||||
= impl Future<Output = Result<(), T::Error>>;
|
||||
|
||||
type WriteFuture<'a, T, Word>
|
||||
where
|
||||
T: SpiDevice + ?Sized + 'a,
|
||||
T::Bus: SpiBusWrite<Word>,
|
||||
Word: Copy + 'static,
|
||||
= impl Future<Output = Result<(), T::Error>>;
|
||||
|
||||
type TransferFuture<'a, T, Word>
|
||||
where
|
||||
T: SpiDevice + ?Sized + 'a,
|
||||
T::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static,
|
||||
= impl Future<Output = Result<(), T::Error>>;
|
||||
|
||||
type TransferInPlaceFuture<'a, T, Word>
|
||||
where
|
||||
T: SpiDevice + ?Sized + 'a,
|
||||
T::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static,
|
||||
= impl Future<Output = Result<(), T::Error>>;
|
||||
|
||||
/// SPI device trait
|
||||
///
|
||||
/// `SpiDevice` represents ownership over a single SPI device on a (possibly shared) bus, selected
|
||||
@@ -45,97 +73,13 @@ pub trait SpiDevice: ErrorType {
|
||||
where
|
||||
F: FnOnce(*mut Self::Bus) -> Fut + 'a,
|
||||
Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>> + 'a;
|
||||
}
|
||||
|
||||
/// Helper methods for SpiDevice.
|
||||
///
|
||||
/// This is automatically implemented for all `T: SpiDevice`, you can directly
|
||||
/// use the methods on any `SpiDevice`.
|
||||
pub trait SpiDeviceExt: SpiDevice {
|
||||
/// Future returned by the `read` method.
|
||||
type ReadFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBusRead<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Do a read within a transaction.
|
||||
///
|
||||
/// This is a convenience method equivalent to `device.transaction(|bus| bus.read(buf))`.
|
||||
///
|
||||
/// See also: [`SpiDevice::transaction`], [`SpiBusRead::read`]
|
||||
fn read<'a, Word>(&'a mut self, buf: &'a mut [Word]) -> Self::ReadFuture<'a, Word>
|
||||
where
|
||||
Self::Bus: SpiBusRead<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Future returned by the `write` method.
|
||||
type WriteFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBusWrite<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Do a write within a transaction.
|
||||
///
|
||||
/// This is a convenience method equivalent to `device.transaction(|bus| bus.write(buf))`.
|
||||
///
|
||||
/// See also: [`SpiDevice::transaction`], [`SpiBusWrite::write`]
|
||||
fn write<'a, Word>(&'a mut self, buf: &'a [Word]) -> Self::WriteFuture<'a, Word>
|
||||
where
|
||||
Self::Bus: SpiBusWrite<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Future returned by the `transfer` method.
|
||||
type TransferFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Do a transfer within a transaction.
|
||||
///
|
||||
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer(read, write))`.
|
||||
///
|
||||
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer`]
|
||||
fn transfer<'a, Word>(
|
||||
&'a mut self,
|
||||
read: &'a mut [Word],
|
||||
write: &'a [Word],
|
||||
) -> Self::TransferFuture<'a, Word>
|
||||
where
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Future returned by the `transfer_in_place` method.
|
||||
type TransferInPlaceFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Do an in-place transfer within a transaction.
|
||||
///
|
||||
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer_in_place(buf))`.
|
||||
///
|
||||
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer_in_place`]
|
||||
fn transfer_in_place<'a, Word>(
|
||||
&'a mut self,
|
||||
buf: &'a mut [Word],
|
||||
) -> Self::TransferInPlaceFuture<'a, Word>
|
||||
where
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static;
|
||||
}
|
||||
|
||||
impl<T: SpiDevice> SpiDeviceExt for T {
|
||||
type ReadFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBusRead<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
fn read<'a, Word>(&'a mut self, buf: &'a mut [Word]) -> Self::ReadFuture<'a, Word>
|
||||
fn read<'a, Word>(&'a mut self, buf: &'a mut [Word]) -> ReadFuture<'a, Self, Word>
|
||||
where
|
||||
Self::Bus: SpiBusRead<Word>,
|
||||
Word: Copy + 'static,
|
||||
@@ -147,13 +91,12 @@ impl<T: SpiDevice> SpiDeviceExt for T {
|
||||
})
|
||||
}
|
||||
|
||||
type WriteFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBusWrite<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
fn write<'a, Word>(&'a mut self, buf: &'a [Word]) -> Self::WriteFuture<'a, Word>
|
||||
/// Do a write within a transaction.
|
||||
///
|
||||
/// This is a convenience method equivalent to `device.transaction(|bus| bus.write(buf))`.
|
||||
///
|
||||
/// See also: [`SpiDevice::transaction`], [`SpiBusWrite::write`]
|
||||
fn write<'a, Word>(&'a mut self, buf: &'a [Word]) -> WriteFuture<'a, Self, Word>
|
||||
where
|
||||
Self::Bus: SpiBusWrite<Word>,
|
||||
Word: Copy + 'static,
|
||||
@@ -165,17 +108,16 @@ impl<T: SpiDevice> SpiDeviceExt for T {
|
||||
})
|
||||
}
|
||||
|
||||
type TransferFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Do a transfer within a transaction.
|
||||
///
|
||||
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer(read, write))`.
|
||||
///
|
||||
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer`]
|
||||
fn transfer<'a, Word>(
|
||||
&'a mut self,
|
||||
read: &'a mut [Word],
|
||||
write: &'a [Word],
|
||||
) -> Self::TransferFuture<'a, Word>
|
||||
) -> TransferFuture<'a, Self, Word>
|
||||
where
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static,
|
||||
@@ -187,16 +129,15 @@ impl<T: SpiDevice> SpiDeviceExt for T {
|
||||
})
|
||||
}
|
||||
|
||||
type TransferInPlaceFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static;
|
||||
|
||||
/// Do an in-place transfer within a transaction.
|
||||
///
|
||||
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer_in_place(buf))`.
|
||||
///
|
||||
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer_in_place`]
|
||||
fn transfer_in_place<'a, Word>(
|
||||
&'a mut self,
|
||||
buf: &'a mut [Word],
|
||||
) -> Self::TransferInPlaceFuture<'a, Word>
|
||||
) -> TransferInPlaceFuture<'a, Self, Word>
|
||||
where
|
||||
Self::Bus: SpiBus<Word>,
|
||||
Word: Copy + 'static,
|
||||
|
||||
Reference in New Issue
Block a user