ratatui_macros/
row.rs

1/// A macro for creating a [`Row`] using vec! syntax.
2///
3/// `row!` is similar to the [`vec!`] macro, but it returns a [`Row`] instead of a `Vec`.
4///
5/// # Examples
6///
7/// * Create a [`Row`] containing a vector of [`Cell`]s:
8///
9/// ```rust
10/// # use ratatui::prelude::*;
11/// use ratatui_macros::row;
12///
13/// let row = row!["hello", "world"];
14/// let row = row!["hello".red(), "world".red().bold()];
15/// ```
16///
17/// * Create an empty [`Row`]:
18///
19/// ```rust
20/// # use ratatui::prelude::*;
21/// # use ratatui_macros::row;
22/// let empty_row = row![];
23/// ```
24///
25/// * Create a [`Row`] from a given [`Cell`] repeated some amount of times:
26///
27/// ```rust
28/// # use ratatui::prelude::*;
29/// # use ratatui_macros::row;
30/// let row = row!["hello"; 2];
31/// ```
32///
33/// * Use [`text!`], [`line!`] or [`span!`] macro inside [`row!`] macro.
34///
35/// ```rust
36/// # use ratatui::prelude::*;
37/// use ratatui_macros::{row, line, text, span};
38///
39/// let row = row![
40///     line!["hello", "world"], span!(Modifier::BOLD; "goodbye {}", "world"),
41///     text!["hello", "world"],
42/// ];
43/// ```
44///
45/// [`Row`]: crate::widgets::Row
46/// [`Cell`]: crate::widgets::Cell
47#[macro_export]
48macro_rules! row {
49    () => {
50        ::ratatui::widgets::Row::default()
51    };
52    ($cell:expr; $n:expr) => {
53        ::ratatui::widgets::Row::new(vec![::ratatui::widgets::Cell::from($cell); $n])
54    };
55    ($($cell:expr),+ $(,)?) => {{
56        ::ratatui::widgets::Row::new(vec![
57        $(
58            ::ratatui::widgets::Cell::from($cell),
59        )+
60        ])
61    }};
62}
63
64#[cfg(test)]
65mod tests {
66
67    use ratatui::{
68        text::Text,
69        widgets::{Cell, Row},
70    };
71
72    #[test]
73    fn row_literal() {
74        let row = row!["hello", "world"];
75        assert_eq!(
76            row,
77            Row::new(vec![Cell::from("hello"), Cell::from("world")])
78        );
79    }
80
81    #[test]
82    fn row_empty() {
83        let row = row![];
84        assert_eq!(row, Row::default());
85    }
86
87    #[test]
88    fn row_single_cell() {
89        let row = row![Cell::from("foo")];
90        assert_eq!(row, Row::new(vec![Cell::from("foo")]));
91    }
92
93    #[test]
94    fn row_repeated_cell() {
95        let row = row![Cell::from("foo"); 2];
96        assert_eq!(row, Row::new(vec![Cell::from("foo"), Cell::from("foo")]));
97    }
98
99    #[test]
100    fn row_explicit_use_of_span_and_line() {
101        let row = row![crate::line!("hello"), crate::span!["world"]];
102        assert_eq!(
103            row,
104            Row::new(vec![Cell::from("hello"), Cell::from("world")])
105        );
106    }
107
108    #[test]
109    fn row_vec_count_syntax() {
110        let row = row!["hello"; 2];
111        assert_eq!(
112            row,
113            Row::new(vec![Cell::from("hello"), Cell::from("hello")])
114        );
115    }
116
117    #[test]
118    fn multiple_rows() {
119        use crate::text;
120        let rows = [
121            row!["Find File", text!["ctrl+f"].right_aligned()],
122            row!["Open recent", text!["ctrl+r"].right_aligned()],
123            row!["Open config", text!["ctrl+k"].right_aligned()],
124        ];
125        assert_eq!(
126            rows,
127            [
128                Row::new([
129                    Cell::from("Find File"),
130                    Cell::from(Text::raw("ctrl+f").alignment(ratatui::layout::Alignment::Right)),
131                ]),
132                Row::new([
133                    Cell::from("Open recent"),
134                    Cell::from(Text::raw("ctrl+r").alignment(ratatui::layout::Alignment::Right)),
135                ]),
136                Row::new([
137                    Cell::from("Open config"),
138                    Cell::from(Text::raw("ctrl+k").alignment(ratatui::layout::Alignment::Right)),
139                ]),
140            ]
141        );
142    }
143}