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).