Struct with iterator?

I’m trying to store an iterator over lines in a struct: It is to be fed via either str::lines() or BufReader::lines().

pub struct LineFactory<'a> {
    line_iter: Box<dyn Iterator<Item = &'a str>>,
}
impl<'a> LineFactory<'a> {
    pub fn new<TLines>(lines: TLines) -> Self
    where
        TLines: IntoIterator<Item = &'a str>,
        TLines::IntoIter: 'static, // (A)
    {
        Self {
            line_iter: Box::new(lines.into_iter()),
        }
    }
}
/// Example of using LineFactory (more complicated in my actual code)
fn create<'a>(str: &'a str) -> LineFactory<'a> {
    // Error: lifetime may not live long enough
    LineFactory::new(str.lines())
}

Line A with 'static seems to be needed but means that create() doesn’t work anymore.

Another attempt. This time invariance becomes an issue:

pub struct LineFactory<'a> {
    line_iter: Box<dyn Iterator<Item = &'a str>>,
}
impl<'a> LineFactory<'a> {
    pub fn new(line_iter: Box<dyn Iterator<Item = &'a str>>) -> Self
    {
        Self {
            line_iter,
        }
    }
}
fn create<'a>(str: &'a str) -> LineFactory<'a> {
    LineFactory::new(Box::new(str.lines()))
}

An iterator that returns owned values would be nice (because there wouldn’t be any references and lifetime annotations anymore) but that seems to conflict with how iterators work:

pub struct LineFactory {
    line_iter: Box<dyn Iterator<Item = String>>,
}
impl LineFactory {
    pub fn new(line_iter: Box<dyn Iterator<Item = String>>) -> Self
    {
        Self {
            line_iter,
        }
    }
}
fn create(str: &str) -> LineFactory {
    LineFactory::new(Box::new(str.lines().map(|s|s.to_string()))) // error
}

Is iteration the wrong tool here? I’d love to have a simple solution (efficiency is less important).

You can write

pub struct LineFactory<'a> {
    line_iter: Box<dyn Iterator<Item = &'a str> + 'a>,
}

Box<dyn Trait> is implcit Box<dyn Trait + 'static>

1 Like

That makes sense, thanks! I didn’t even consider that due to the compiler’s error message.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.