I've got code that looks (a little) like this:
struct OutputIterator<'r, 'i: 'r> {
input_handler: &'r mut InputHandler<'i>
}
impl<'r, 'i> Iterator for OutputIterator<'r, 'i> {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
self.input_handler.inputs.next().map(|x| x * 2)
}
}
struct InputHandler<'a> {
inputs: Box<dyn Iterator<Item = i32> + 'a>
}
impl<'a> InputHandler<'a> {
fn outputs<'b>(&'b mut self) -> OutputIterator<'b, 'a> {
OutputIterator { input_handler: self }
}
}
fn main() {
let mut input_handler = InputHandler {
inputs: Box::new(vec![1,2,3,4,5].into_iter())
};
for output in input_handler.outputs() {
println!("{}", output);
}
}
Basically, the user can supply an iterator of inputs, and then get an iterator of outputs (in my real code the connection between inputs and outputs is much more complex involving a bunch of internal state. Multiple inputs might go towards one output or vice-versa).
This works, but I would like to change it use impl Iterator both to hide the OutputIterator type and to allow for easier swapping out of the return type in testing with a fake. My best attempt at that changes the InputHandler impl like so:
impl<'a> InputHandler<'a> {
fn outputs<'b>(&'b mut self) -> impl Iterator<Item = i32> + 'b {
OutputIterator { input_handler: self }
}
}
Unfortunately, that gets me: error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
Is there a way to make this work? It's important for the interface that InputHandler take an iterator with some lifetime, and that obviously has to be passed on to the OutputIterator somehow, but I'd really like to abstract those details away from the caller. In principle, the caller should only have to worry about making sure that the inputs Iterator and InputHandler outlive the OutputIterator so I think the logical lifetime bound on the OutputIterator here is the smaller of those two? Any clarity on why this error is happening or how to fix it would be great!
In case it helps, here's a rust playground with the code in it.