Description
I was recently porting an I2C controller device to 1.0.0-alpha.7
which forced me to implement transaction
and transaction_iter
for the first time. I initially tried to implement transaction
as follows:
fn transaction<'a>(
&mut self,
address: u8,
operations: &mut [Operation<'a>],
) -> Result<(), Self::Error> {
self.transaction_iter(address, operations)
}
This, of course, did not work as &mut [Operation<'a>]
produces an iterator with Item = &mut Operation<'a>
rather than the Item = Operation<'a>
that transaction_iter
requires.
fn transaction_iter<'a, O>(&mut self, address: u8, operations: O) -> Result<(), Self::Error>
where
O: IntoIterator<Item = Operation<'a>>,
In my opinion, transaction_iter
's signature should be this instead:
fn transaction_iter<'a, 'b: 'a, O>(&mut self, address: u8, operations: O) -> Result<(), Self::Error>
where
O: IntoIterator<Item = &'a Operation<'b>>,
This signature mainly allows the implementation of transaction
that I wrote above. By changing this signature almost all functions of I2C
can be implemented as calls to transaction_iter
even on systems without alloc
support, with write_iter
and write_iter_read
being the exceptions. This would allow de-duplication of logic, which is rarely a bad thing. Additionally, I see no reason that transaction_iter
needs an iterator over owned Operations
in the first place.
Thoughts?