Accepting a function returning an opaque iterator borrowing from the input

⚓ rust    📅 2025-05-28    👤 surdeus    👁️ 3      

surdeus

Warning

This post was published 32 days ago. The information described in this article may have changed.

The following code works:

struct MyState(Vec<usize>);

fn logic(state: &mut MyState) -> impl Iterator<Item = usize> {
    state.0.iter().cloned()
}

struct Engine<State, Logic> {
    state: State,
    logic: Logic,
}

impl<State, Logic> Engine<State, Logic> {
    fn run<'a, Iter>(&'a mut self)
    where
        Logic: FnMut(&'a mut State) -> Iter,
        Iter: Iterator<Item = usize> + 'a,
    {
        for x in (self.logic)(&mut self.state) {
            println!("got {x}");
        }
    }
}

fn main() {
    let state = MyState(vec![1, 2, 3]);
    let mut engine = Engine { state, logic };
    engine.run();
    engine.run();
}

I'd now like to change it so that Engine::run consumes self rather than taking &mut self but I am struggling to figure it out. Note that:

  1. I want the logic function to return a opaque type. I don't want to Box or dynamic dispatch anything.
  2. The iterator returned in the logic function borrows from the passed in state. (I don't want + use<> on the logic function return type).
  3. The logic function should be able to be called multiple times. (Also doesn't work with the above code).

5 posts - 3 participants

Read full topic

🏷️ rust_feed