docs(examples): Remove lifetimes from the List example (#1132)

Simplify the List example by removing lifetimes not strictly necessary
to demonstrate how Ratatui lists work. Instead, the sample strings are
copied into each `TodoItem`. To further simplify, I changed the code to
use a new TodoItem::new function, rather than an implementation of the
`From` trait.
This commit is contained in:
Matt Armstrong 2024-05-24 15:09:24 -07:00 committed by GitHub
parent 4770e71581
commit f429f688da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -38,15 +38,25 @@ enum Status {
Completed,
}
struct TodoItem<'a> {
todo: &'a str,
info: &'a str,
struct TodoItem {
todo: String,
info: String,
status: Status,
}
struct StatefulList<'a> {
impl TodoItem {
fn new(todo: &str, info: &str, status: Status) -> Self {
Self {
todo: todo.to_string(),
info: info.to_string(),
status,
}
}
}
struct TodoList {
state: ListState,
items: Vec<TodoItem<'a>>,
items: Vec<TodoItem>,
last_selected: Option<usize>,
}
@ -56,8 +66,8 @@ struct StatefulList<'a> {
///
/// Check the event handling at the bottom to see how to change the state on incoming events.
/// Check the drawing logic for items on how to specify the highlighting style for selected items.
struct App<'a> {
items: StatefulList<'a>,
struct App {
items: TodoList,
}
fn main() -> Result<(), Box<dyn Error>> {
@ -102,10 +112,10 @@ fn restore_terminal() -> color_eyre::Result<()> {
Ok(())
}
impl<'a> App<'a> {
impl App {
fn new() -> Self {
Self {
items: StatefulList::with_items([
items: TodoList::with_items(&[
("Rewrite everything with Rust!", "I can't hold my inner voice. He tells me to rewrite the complete universe with Rust", Status::Todo),
("Rewrite all of your tui apps with Ratatui", "Yes, you heard that right. Go and replace your tui with Ratatui.", Status::Completed),
("Pet your cat", "Minnak loves to be pet by you! Don't forget to pet and give some treats!", Status::Todo),
@ -135,7 +145,7 @@ impl<'a> App<'a> {
}
}
impl App<'_> {
impl App {
fn run(&mut self, mut terminal: Terminal<impl Backend>) -> io::Result<()> {
loop {
self.draw(&mut terminal)?;
@ -164,7 +174,7 @@ impl App<'_> {
}
}
impl Widget for &mut App<'_> {
impl Widget for &mut App {
fn render(self, area: Rect, buf: &mut Buffer) {
// Create a space for header, todo list and the footer.
let vertical = Layout::vertical([
@ -186,7 +196,7 @@ impl Widget for &mut App<'_> {
}
}
impl App<'_> {
impl App {
fn render_todo(&mut self, area: Rect, buf: &mut Buffer) {
// We create two blocks, one is for the header (outer) and the other is for list (inner).
let outer_block = Block::new()
@ -238,8 +248,8 @@ impl App<'_> {
// We get the info depending on the item's state.
let info = if let Some(i) = self.items.state.selected() {
match self.items.items[i].status {
Status::Completed => "✓ DONE: ".to_string() + self.items.items[i].info,
Status::Todo => "TODO: ".to_string() + self.items.items[i].info,
Status::Completed => format!("✓ DONE: {}", self.items.items[i].info),
Status::Todo => format!("TODO: {}", self.items.items[i].info),
}
} else {
"Nothing to see here...".to_string()
@ -288,11 +298,14 @@ fn render_footer(area: Rect, buf: &mut Buffer) {
.render(area, buf);
}
impl StatefulList<'_> {
fn with_items<'a>(items: [(&'a str, &'a str, Status); 6]) -> StatefulList<'a> {
StatefulList {
impl TodoList {
fn with_items(items: &[(&str, &str, Status)]) -> Self {
Self {
state: ListState::default(),
items: items.iter().map(TodoItem::from).collect(),
items: items
.iter()
.map(|(todo, info, status)| TodoItem::new(todo, info, *status))
.collect(),
last_selected: None,
}
}
@ -333,7 +346,7 @@ impl StatefulList<'_> {
}
}
impl TodoItem<'_> {
impl TodoItem {
fn to_list_item(&self, index: usize) -> ListItem {
let bg_color = match index % 2 {
0 => NORMAL_ROW_COLOR,
@ -350,13 +363,3 @@ impl TodoItem<'_> {
ListItem::new(line).bg(bg_color)
}
}
impl<'a> From<&(&'a str, &'a str, Status)> for TodoItem<'a> {
fn from((todo, info, status): &(&'a str, &'a str, Status)) -> Self {
Self {
todo,
info,
status: *status,
}
}
}