I am trying to implement a default iterator for structs implementing a trait. My trait is called DataRow
, represents a row of table cells, and looks like this:
pub trait DataRow<'a> {
// Gets a cell by index
fn getCell(&self, i: usize) -> &DataCell<'a>;
// Gets the number of cells in the row
fn getNumCells(&self) -> usize;
}
The default iterator I want to provide should use those two methods to iterate over the row and return cell references. In Java this would boil down to an abstract class DataRow
that implements Iterable
. In Rust I tried first with IntoIterator
:
impl<'a, T> IntoIterator for &'a T
where
T: DataRow<'a>,
{
type Item = &'a DataCell<'a>;
type IntoIter = DataRowIterator<'a, T>;
fn into_iter(self) -> DataRowIterator<'a, T> {
return DataRowIterator::new(self);
}
}
This does not work as anyone could implement their own iterator for their own implementation of the DataRow
trait.
My second try was adding an iter
method to the trait which creates the iterator and returns it:
fn iter(&self) -> DataRowIterator<'a, Self> {
return DataRowIterator::new(self);
}
This does not work either, because the size of Self
is not known at compile time. Since DataRow
can contain an arbitrary number of cells, I also cannot mark it as Sized
to get around that.
My demo code including notes on the occurring errors
How would someone implement such a "default iterator" for a custom trait?
You can implement IntoIterator
for a trait object reference.
impl<'a> IntoIterator for &'a DataRow<'a> {
type Item = &'a DataCell<'a>;
type IntoIter = DataRowIterator<'a>;
fn into_iter(self) -> DataRowIterator<'a> {
DataRowIterator::new(self)
}
}
DataRowIterator
should be modified to keep the trait object reference &DataRow
instead of &T
and use the methods available for the DataRow
trait.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With