Hi All,
I'm having a row with the compiler and hoping you can set me straight!
The concept is that I have some images which are re-arranged by row. I have sources where the original data makes sense to be owned but I would like the option of it to be borrowed from the original source to avoid a copy if it will immediately be copied to the final image anyway.
Great I thought! I can have a trait for a data reader which allows me to fetch an iterator of the rows where each row is represented as a slice.
I've struggled with lifetimes but seem to have appeased the compiler on that (but feels like I've just done whats asked so let me know if there appears to be a simpler way!)
However I'm struggling with returning a valid Iterator object. The owned items iteration is generated by chunks of the stored vector. The borrowed items is an iterator over a vector. I thought I can use -> impl Iterator<Item=T>
but that complains because it can't be a return in a trait?
So I found another thread that pointed me to the solution below. Creating a generic type parameter on the impl block and making this the iterator trait. (I'm also aware of Box but performance is very important so I avoided this)
However this still fails to compile.
What am I missing? How can I get this to work and/or am I missing a better design? (I often find this is the case when fighting the compiler)
pub trait ChipRowReader<'a, T: 'a, I: Iterator<Item=&'a&'a[T]>> {
fn row_iter(&self) -> I;
}
struct BorrowedChipData<'a,T: Copy> {
data: Vec<&'a[T]>
}
impl<'a, T:Copy> BorrowedChipData<'a,T> {
fn new(rows: usize, columns: usize) -> Self {
return Self{
data: Vec::with_capacity(rows)
};
}
fn push_row(&mut self, row: &'a [T]) {
self.data.push(row);
}
}
impl<'a, T: Copy, I: Iterator<Item=&'a&'a[T]>> ChipRowReader<'a, T, I> for BorrowedChipData<'a, T> {
fn row_iter(&self) -> I {
self.data.iter()
}
}
struct OwnedChipData<T: Copy> {
columns: usize,
data: Vec<T>
}
impl<T: Copy> OwnedChipData<T> {
fn new(rows: usize, columns: usize) -> Self {
return Self{
columns: columns,
data: Vec::with_capacity(rows * columns)
};
}
fn push_row(&mut self, row: & [T]) {
self.data.extend_from_slice(row);
}
}
impl<'a, T: 'a + Copy, I: Iterator<Item=&'a&'a[T]>> ChipRowReader<'a, T, I> for OwnedChipData<T> {
fn row_iter(& self) -> I {
let data = self.data;
&data[..].chunks(self.columns)
}
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/lib.rs:28:9
|
25 | impl<'a, T: Copy, I: Iterator<Item=&'a&'a[T]>> ChipRowReader<'a, T, I> for BorrowedChipData<'a, T> {
| - this type parameter
26 |
27 | fn row_iter(&self) -> I {
| - expected `I` because of return type
28 | self.data.iter()
| ^^^^^^^^^^^^^^^^ expected type parameter `I`, found struct `std::slice::Iter`
|
= note: expected type parameter `I`
found struct `std::slice::Iter<'_, &[T]>`
error[E0308]: mismatched types
--> src/lib.rs:55:9
|
49 | impl<'a, T: 'a + Copy, I: Iterator<Item=&'a&'a[T]>> ChipRowReader<'a, T, I> for OwnedChipData<T> {
| - this type parameter
...
52 | fn row_iter(& self) -> I {
| - expected `I` because of return type
...
55 | &data[..].chunks(self.columns)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `I`, found `&Chunks<'_, T>`
|
= note: expected type parameter `I`
found reference `&Chunks<'_, T>`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors