Skip to content

Commit 3b8a4f8

Browse files
bors[bot]Dirbaio
andauthored
Merge #382
382: async/spi: make helpers default methods instead of an extension trait. r=ryankurte a=Dirbaio 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. Co-authored-by: Dario Nieuwenhuis <[email protected]>
2 parents 58587e8 + 14103be commit 3b8a4f8

File tree

1 file changed

+47
-106
lines changed

1 file changed

+47
-106
lines changed

embedded-hal-async/src/spi.rs

Lines changed: 47 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,34 @@ pub use embedded_hal::spi::{
77
};
88
use embedded_hal::{digital::blocking::OutputPin, spi::blocking};
99

10+
type ReadFuture<'a, T, Word>
11+
where
12+
T: SpiDevice + ?Sized + 'a,
13+
T::Bus: SpiBusRead<Word>,
14+
Word: Copy + 'static,
15+
= impl Future<Output = Result<(), T::Error>>;
16+
17+
type WriteFuture<'a, T, Word>
18+
where
19+
T: SpiDevice + ?Sized + 'a,
20+
T::Bus: SpiBusWrite<Word>,
21+
Word: Copy + 'static,
22+
= impl Future<Output = Result<(), T::Error>>;
23+
24+
type TransferFuture<'a, T, Word>
25+
where
26+
T: SpiDevice + ?Sized + 'a,
27+
T::Bus: SpiBus<Word>,
28+
Word: Copy + 'static,
29+
= impl Future<Output = Result<(), T::Error>>;
30+
31+
type TransferInPlaceFuture<'a, T, Word>
32+
where
33+
T: SpiDevice + ?Sized + 'a,
34+
T::Bus: SpiBus<Word>,
35+
Word: Copy + 'static,
36+
= impl Future<Output = Result<(), T::Error>>;
37+
1038
/// SPI device trait
1139
///
1240
/// `SpiDevice` represents ownership over a single SPI device on a (possibly shared) bus, selected
@@ -45,97 +73,13 @@ pub trait SpiDevice: ErrorType {
4573
where
4674
F: FnOnce(*mut Self::Bus) -> Fut + 'a,
4775
Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>> + 'a;
48-
}
49-
50-
/// Helper methods for SpiDevice.
51-
///
52-
/// This is automatically implemented for all `T: SpiDevice`, you can directly
53-
/// use the methods on any `SpiDevice`.
54-
pub trait SpiDeviceExt: SpiDevice {
55-
/// Future returned by the `read` method.
56-
type ReadFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
57-
where
58-
Self: 'a,
59-
Self::Bus: SpiBusRead<Word>,
60-
Word: Copy + 'static;
6176

6277
/// Do a read within a transaction.
6378
///
6479
/// This is a convenience method equivalent to `device.transaction(|bus| bus.read(buf))`.
6580
///
6681
/// See also: [`SpiDevice::transaction`], [`SpiBusRead::read`]
67-
fn read<'a, Word>(&'a mut self, buf: &'a mut [Word]) -> Self::ReadFuture<'a, Word>
68-
where
69-
Self::Bus: SpiBusRead<Word>,
70-
Word: Copy + 'static;
71-
72-
/// Future returned by the `write` method.
73-
type WriteFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
74-
where
75-
Self: 'a,
76-
Self::Bus: SpiBusWrite<Word>,
77-
Word: Copy + 'static;
78-
79-
/// Do a write within a transaction.
80-
///
81-
/// This is a convenience method equivalent to `device.transaction(|bus| bus.write(buf))`.
82-
///
83-
/// See also: [`SpiDevice::transaction`], [`SpiBusWrite::write`]
84-
fn write<'a, Word>(&'a mut self, buf: &'a [Word]) -> Self::WriteFuture<'a, Word>
85-
where
86-
Self::Bus: SpiBusWrite<Word>,
87-
Word: Copy + 'static;
88-
89-
/// Future returned by the `transfer` method.
90-
type TransferFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
91-
where
92-
Self: 'a,
93-
Self::Bus: SpiBus<Word>,
94-
Word: Copy + 'static;
95-
96-
/// Do a transfer within a transaction.
97-
///
98-
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer(read, write))`.
99-
///
100-
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer`]
101-
fn transfer<'a, Word>(
102-
&'a mut self,
103-
read: &'a mut [Word],
104-
write: &'a [Word],
105-
) -> Self::TransferFuture<'a, Word>
106-
where
107-
Self::Bus: SpiBus<Word>,
108-
Word: Copy + 'static;
109-
110-
/// Future returned by the `transfer_in_place` method.
111-
type TransferInPlaceFuture<'a, Word>: Future<Output = Result<(), Self::Error>> + 'a
112-
where
113-
Self: 'a,
114-
Self::Bus: SpiBus<Word>,
115-
Word: Copy + 'static;
116-
117-
/// Do an in-place transfer within a transaction.
118-
///
119-
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer_in_place(buf))`.
120-
///
121-
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer_in_place`]
122-
fn transfer_in_place<'a, Word>(
123-
&'a mut self,
124-
buf: &'a mut [Word],
125-
) -> Self::TransferInPlaceFuture<'a, Word>
126-
where
127-
Self::Bus: SpiBus<Word>,
128-
Word: Copy + 'static;
129-
}
130-
131-
impl<T: SpiDevice> SpiDeviceExt for T {
132-
type ReadFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
133-
where
134-
Self: 'a,
135-
Self::Bus: SpiBusRead<Word>,
136-
Word: Copy + 'static;
137-
138-
fn read<'a, Word>(&'a mut self, buf: &'a mut [Word]) -> Self::ReadFuture<'a, Word>
82+
fn read<'a, Word>(&'a mut self, buf: &'a mut [Word]) -> ReadFuture<'a, Self, Word>
13983
where
14084
Self::Bus: SpiBusRead<Word>,
14185
Word: Copy + 'static,
@@ -147,13 +91,12 @@ impl<T: SpiDevice> SpiDeviceExt for T {
14791
})
14892
}
14993

150-
type WriteFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
151-
where
152-
Self: 'a,
153-
Self::Bus: SpiBusWrite<Word>,
154-
Word: Copy + 'static;
155-
156-
fn write<'a, Word>(&'a mut self, buf: &'a [Word]) -> Self::WriteFuture<'a, Word>
94+
/// Do a write within a transaction.
95+
///
96+
/// This is a convenience method equivalent to `device.transaction(|bus| bus.write(buf))`.
97+
///
98+
/// See also: [`SpiDevice::transaction`], [`SpiBusWrite::write`]
99+
fn write<'a, Word>(&'a mut self, buf: &'a [Word]) -> WriteFuture<'a, Self, Word>
157100
where
158101
Self::Bus: SpiBusWrite<Word>,
159102
Word: Copy + 'static,
@@ -165,17 +108,16 @@ impl<T: SpiDevice> SpiDeviceExt for T {
165108
})
166109
}
167110

168-
type TransferFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
169-
where
170-
Self: 'a,
171-
Self::Bus: SpiBus<Word>,
172-
Word: Copy + 'static;
173-
111+
/// Do a transfer within a transaction.
112+
///
113+
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer(read, write))`.
114+
///
115+
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer`]
174116
fn transfer<'a, Word>(
175117
&'a mut self,
176118
read: &'a mut [Word],
177119
write: &'a [Word],
178-
) -> Self::TransferFuture<'a, Word>
120+
) -> TransferFuture<'a, Self, Word>
179121
where
180122
Self::Bus: SpiBus<Word>,
181123
Word: Copy + 'static,
@@ -187,16 +129,15 @@ impl<T: SpiDevice> SpiDeviceExt for T {
187129
})
188130
}
189131

190-
type TransferInPlaceFuture<'a, Word> = impl Future<Output = Result<(), Self::Error>> + 'a
191-
where
192-
Self: 'a,
193-
Self::Bus: SpiBus<Word>,
194-
Word: Copy + 'static;
195-
132+
/// Do an in-place transfer within a transaction.
133+
///
134+
/// This is a convenience method equivalent to `device.transaction(|bus| bus.transfer_in_place(buf))`.
135+
///
136+
/// See also: [`SpiDevice::transaction`], [`SpiBus::transfer_in_place`]
196137
fn transfer_in_place<'a, Word>(
197138
&'a mut self,
198139
buf: &'a mut [Word],
199-
) -> Self::TransferInPlaceFuture<'a, Word>
140+
) -> TransferInPlaceFuture<'a, Self, Word>
200141
where
201142
Self::Bus: SpiBus<Word>,
202143
Word: Copy + 'static,

0 commit comments

Comments
 (0)