Reputation: 369
I am new to rust and I am building a TUI app using rust-tui to practice and understand the concepts of rust. I have this code:
// the widgets that can be renderd on the screen
#[derive(Clone)]
pub enum Widgets<'a> {
ResList(ResList<'a>),
ListResults(ListResults<'a>),
Input(Input),
}
pub struct Screen<'a> {
renders_done: u32,
tx: Sender<Result<Event, crossterm::ErrorKind>>,
rx: Receiver<Result<Event, crossterm::ErrorKind>>,
main_screen: Widgets<'a>,
}
impl Screen<'_> {
pub async fn handle_events(&mut self) {
let event = self
.rx
.recv()
.expect("Err while recievent the events in the reciever")
.unwrap();
let new_screen: Option<Widgets> = match &mut self.main_screen {
Widgets::ResList(res_list) => {
match event {
Event::Key(event) => match event.code {
KeyCode::Esc => {
Screen::exit_app();
None
}
_ => None,
}
}
Widgets::Input(input) => input.handle_events(event).await, <-- the problem comes when I add this
_ => None,
};
match new_screen {
Some(screen) => self.main_screen = screen,
None => {}
}
}
}
impl Input {
async fn handle_events(&mut self, event: Event) -> Option<Widgets> {
None
}
}
The idea is that if a sub-module returns a widget the main screen should be changed to that new widget. For texting purposes for now I never return a widget. But when I try and build the code the compiler complains:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/model/tui/screen.rs:84:32
|
84 | pub async fn handle_events(&mut self) {
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the method body at 84:32...
--> src/model/tui/screen.rs:84:32
|
84 | pub async fn handle_events(&mut self) {
| ^
note: ...so that the expression is assignable
--> src/model/tui/screen.rs:84:32
|
84 | pub async fn handle_events(&mut self) {
| ^^^^^^^^^
= note: expected `&mut Screen<'_>`
found `&mut Screen<'_>`
note: but, the lifetime must be valid for the lifetime `'_` as defined on the impl at 45:13...
--> src/model/tui/screen.rs:45:13
|
45 | impl Screen<'_> {
| ^^
note: ...so that the expression is assignable
--> src/model/tui/screen.rs:126:52
|
126 | Some(mut screen) => self.main_screen = screen,
| ^^^^^^
= note: expected `Widgets<'_>`
found `Widgets<'_>`
error: aborting due to previous error; 8 warnings emitted
For more information about this error, try `rustc --explain E0495`.
From what I understand the lifetimes are not living enough to be saved in the struct but I am not using references anywhere they are all owned values. Can someone help me understand what am I missing?
Upvotes: 1
Views: 129
Reputation: 369
Specify the lifetimes explicitly on the widget returned and create an explicit lifetime of the object:
impl<'screen> Screen<'screen> {
pub async fn handle_events<'c>(&'cmut self) {
let event = self
.rx
.recv()
.expect("Err while recievent the events in the reciever")
.unwrap();
let new_screen: Option<Widgets<'screen>> = match &mut self.main_screen {
Widgets::ResList(res_list) => {
match event {
Event::Key(event) => match event.code {
KeyCode::Esc => {
Screen::exit_app();
None
}
_ => None,
}
}
Widgets::Input(input) => input.handle_events(event).await,
_ => None,
};
match new_screen {
Some(screen) => self.main_screen = screen,
None => {}
}
}
}
Also add the lifetime explicitly when returning a Widget from inside a function
Upvotes: 0