I am using the Cursive TUI crate and I am having trouble with a dialog button because I want to set an input to change with the dialog response. This is my code:
fn prompt_repeat(siv: &mut Cursive) -> bool {
let input = Cell::new(false);
siv.add_layer(views::Dialog::text("Do you want to retype the note again?")
.title("Redo?")
.button("Yes", |s| {
input.set(true);
s.quit();
})
.button("No", |s| {
s.quit();
}));
siv.run();
input.get()
}
This causes error E0373:
error[E0373]: closure may outlive the current function, but it borrows `input`, which is owned by the current function
--> src/main.rs:94:23
|
94 | .button("No", |s| {
| ^^^ may outlive borrowed value `input`
95 | input.set(false)
| ----- `input` is borrowed here
|
note: function requires argument type to outlive `'static`
--> src/main.rs:89:19
|
89 | siv.add_layer(views::Dialog::text("Do you want to retype the note again?")
| ___________________^
90 | | .title("Redo?")
91 | | .button("Yes", |s| {
92 | | input.set(true)
... |
95 | | input.set(false)
96 | | })
| |______________^
help: to force the closure to take ownership of `input` (and any other referenced variables), use the `move` keyword
|
94 | .button("No", move |s| {
| ++++
I understand that this is caused because the compiler cannot know if input
will still exist before the closure uses it, but I cannot use move
because I need to reference the cell again to return it (I have tried this and the compiler tells me I have borrowed the value multiple times, which is correct).
How should I go about referencing the cell in multiple closures?
I agree with @Jmb, I'd probably go with a Rc
reference counting smart pointer:
fn prompt_repeat(siv: &mut Cursive) -> bool {
let input = Rc::new(Cell::new(false));
let input_2 = input.clone();
siv.add_layer(
views::Dialog::text("Do you want to retype the note again?")
.title("Redo?")
.button("Yes", move |s| {
input_2.set(true);
s.quit();
})
.button("No", move |s| {
s.quit();
}),
);
siv.run();
input.get()
}