From e64e194b6bc5f89c68fe73d430e63c264af6ca4f Mon Sep 17 00:00:00 2001 From: Eric Lunderberg Date: Sat, 6 Jan 2024 22:23:38 -0600 Subject: [PATCH] feat(table): Implement FromIterator for widgets::Row (#755) The `Row::new` constructor accepts a single argument that implements `IntoIterator`. This commit adds an implementation of `FromIterator`, as a thin wrapper around `Row::new`. This allows `.collect::()` to be used at the end of an iterator chain, rather than wrapping the entire iterator chain in `Row::new`. --- examples/table.rs | 19 +++++++++++-------- src/widgets/table/row.rs | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/examples/table.rs b/examples/table.rs index 5a2a4825..9df72e60 100644 --- a/examples/table.rs +++ b/examples/table.rs @@ -118,17 +118,17 @@ fn ui(f: &mut Frame, app: &mut App) { let selected_style = Style::default().add_modifier(Modifier::REVERSED); let normal_style = Style::default().bg(Color::Blue); - let header_cells = ["Header1", "Header2", "Header3"] + let header = ["Header1", "Header2", "Header3"] .iter() - .map(|h| Cell::from(*h).style(Style::default().fg(Color::Red))); - let header = Row::new(header_cells) + .map(|h| Cell::from(*h).style(Style::default().fg(Color::Red))) + .collect::() .style(normal_style) .height(1) .bottom_margin(1); - let footer_cells = ["Footer1", "Footer2", "Footer3"] + let footer = ["Footer1", "Footer2", "Footer3"] .iter() - .map(|f| Cell::from(*f).style(Style::default().fg(Color::Yellow))); - let footer = Row::new(footer_cells) + .map(|f| Cell::from(*f).style(Style::default().fg(Color::Yellow))) + .collect::() .style(normal_style) .height(1) .top_margin(1); @@ -139,8 +139,11 @@ fn ui(f: &mut Frame, app: &mut App) { .max() .unwrap_or(0) + 1; - let cells = item.iter().map(|c| Cell::from(*c)); - Row::new(cells).height(height as u16).bottom_margin(1) + item.iter() + .cloned() + .collect::() + .height(height as u16) + .bottom_margin(1) }); let t = Table::new( rows, diff --git a/src/widgets/table/row.rs b/src/widgets/table/row.rs index ec7598c1..ddad81bf 100644 --- a/src/widgets/table/row.rs +++ b/src/widgets/table/row.rs @@ -45,6 +45,14 @@ use crate::prelude::*; /// ]); /// ``` /// +/// An iterator whose item type is convertible into [`Text`] can be collected into a row. +/// +/// ```rust +/// use ratatui::widgets::Row; +/// +/// (0..10).map(|i| format!("{i}")).collect::(); +/// ``` +/// /// `Row` implements [`Styled`] which means you can use style shorthands from the [`Stylize`] trait /// to set the style of the row concisely. /// @@ -235,6 +243,15 @@ impl<'a> Styled for Row<'a> { } } +impl<'a, Item> FromIterator for Row<'a> +where + Item: Into>, +{ + fn from_iter>(cells: IterCells) -> Self { + Row::new(cells) + } +} + #[cfg(test)] mod tests { use std::vec; @@ -249,6 +266,13 @@ mod tests { assert_eq!(row.cells, cells); } + #[test] + fn collect() { + let cells = vec![Cell::from("")]; + let row: Row = cells.iter().cloned().collect(); + assert_eq!(row.cells, cells); + } + #[test] fn cells() { let cells = vec![Cell::from("")];