I want to make an iterator that owns another iterator and gives items based on that other iterator. Originally, the inner iterator is formed from the result of a database query, it gives the raw data rows as arrived from the DB. The outer iterator takes items of the inner iterator and puts them into a struct that is meaningful within my program. Because different software versions store the same data in different database table structures, I have a parser trait that takes a row and creates a structure. My outer iterator takes two parameters for creation: the iterator for the DB rows and an object which implements how to parse the data.
But I run into a lifetime error which I don't really see the reason of, and following the compiler's hints only lead me in circles. I literally follow the compiler's advice and getting back to the same problem. I tried to minic the code and bring it to a minimal form to reproduce the same compiler errors I'm getting. I'm not entirely sure if it could be minimized further, but I also wanted it to resemble my real code.
Here is the sample:
struct Storeroom<'a> {
    storeroom_id: i64,
    version: &'a str
}
trait StoreroomParser {
    fn parse(&self, row: Row) -> Result<Storeroom, Error>;
}
struct StoreroomParserX;
impl StoreroomParser for StoreroomParserX {
    fn parse(&self, row: Row) -> Result<Storeroom, Error> {
        Ok(Storeroom { storeroom_id: row.dummy, version: "0.0.0"})
    }
}
struct StoreroomIterator {
    rows: Box<dyn Iterator<Item = Row>>,
    parser: Box<dyn StoreroomParser>
}
impl StoreroomIterator {
    fn new() -> Result<Self, Error> {
        let mut rows: Vec<Row> = vec![];
        rows.push(Row { dummy: 4});
        rows.push(Row { dummy: 6});
        rows.push(Row { dummy: 8});
        let rows = Box::new(rows.into_iter());
        let parser = Box::new(StoreroomParserX {});
        Ok(Self {rows, parser})
    }
}
impl Iterator for StoreroomIterator {
    type Item<'a> = Result<Storeroom<'a>, Error>;
    fn next(&mut self) -> Option<Self::Item> {
        if let Some(nextrow) = self.rows.next() {
            Some(self.parser.parse(nextrow))
        }
        else {
            None
        }
    }
}
During my first attempt, the compiler suggested to add a lifetime annotation to the Item type declaration, because it uses a struct that requires a lifetime. But this resulted in the following error:
error[E0658]: generic associated types are unstable
  --> src/main.rs:59:5
   |
59 |     type Item<'a> = Result<Storeroom<'a>, Error>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
  --> src/main.rs:59:14
   |
59 |     type Item<'a> = Result<Storeroom<'a>, Error>;
   |              ^^^^ lifetimes do not match type in trait
Here's the sample code on Playground.
When I tried to mitigate this by moving the lifetime annotation to the impl block instead, I provoked the following error I can't progress from:
error: lifetime may not live long enough
  --> src/main.rs:61:13
   |
56 | impl<'a> Iterator for StoreroomIterator<'a> {
   |      -- lifetime `'a` defined here
...
59 |     fn next(&mut self) -> Option<Self::Item> {
   |             - let's call the lifetime of this reference `'1`
60 |         if let Some(nextrow) = self.rows.next() {
61 |             Some(self.parser.parse(nextrow))
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
I've been stuck on this problem for about a week now. Do you have any ideas how to resolve these errors? I'm also thinking that I should probably just use map() on the rows with whatever closure it takes to properly convert the data, but at this point it would definitely feel like a compromise.
 
     
    