How to increment an iterator with a button using Cursive

Viewed 50

I have been trying this for a couple of days. The following minimal examples shows the status of my current problem:

I have an iterator that references an external slice. I want to advance it (call next()) from within a button.

Cargo.toml

[dependencies]
cursive = "0.18"

main.rs

use cursive::views::Dialog;
use cursive::Cursive;

fn main() {
    let slice = [1, 2, 3, 4, 5, 6];
    let mut chunks = slice.chunks_exact(2);

    let mut siv = cursive::default();
    siv.add_layer(
        Dialog::text("...")
            .button("Quit", |s| s.quit())
            .button("Next", |s| next_thing(s, &mut chunks)),
    );
    siv.run();
}

fn next_thing<'a, I>(_: &mut Cursive, things: &mut I)
where
    I: Iterator<Item = &'a [u8]>,
{
    // I want to call things.next() and to something with the slice.
}

But the closure cannot take mutable references. After many failed attempts, I also found out that Cursive has this function to store user data, but I can't keep my iterator there because its not 'static.

1 Answers
use cursive::views::Dialog;
use cursive::Cursive;
use std::cell::RefCell;
use std::sync::Arc;

const SLICE: [u8; 6] = [1, 2, 3, 4, 5, 6];

fn main() {
    let chunks = Arc::new(RefCell::new(SLICE.chunks_exact(2)));

    let mut siv = cursive::default();
    siv.add_layer(
        Dialog::text("...")
            .button("Quit", |s| s.quit())
            .button("Next", move |s| next_thing(s, &chunks)),
    );
    siv.run();
}

fn next_thing<'a, I>(_: &mut Cursive, things: &Arc<RefCell<I>>)
    where
        I: Iterator<Item = &'a [u8]>,
{
    eprintln!("{:?}", things.borrow_mut().next());
}
Related