diff --git a/Cargo.toml b/Cargo.toml index c4bd1fe0..f6d0f097 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ rust-version = "1.65.0" default = ["crossterm"] all-widgets = ["widget-calendar"] widget-calendar = ["time"] +macros = [] [package.metadata.docs.rs] all-features = true diff --git a/Makefile.toml b/Makefile.toml index e04cca8f..3077c9a6 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -118,15 +118,15 @@ args = [ ] [tasks.test-crossterm] -env = { TUI_FEATURES = "serde,crossterm,all-widgets" } +env = { TUI_FEATURES = "serde,crossterm,all-widgets,macros" } run_task = "test" [tasks.test-termion] -env = { TUI_FEATURES = "serde,termion,all-widgets" } +env = { TUI_FEATURES = "serde,termion,all-widgets,macros" } run_task = "test" [tasks.test-termwiz] -env = { TUI_FEATURES = "serde,termwiz,all-widgets" } +env = { TUI_FEATURES = "serde,termwiz,all-widgets,macros" } run_task = "test" [tasks.test] diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 00e21642..7d92a77f 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -185,3 +185,41 @@ pub trait StatefulWidget { type State; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State); } + +/// Macro that constructs and returns a [`Borders`] object from TOP, BOTTOM, LEFT, RIGHT, NONE, and ALL. +/// Internally it creates an empty `Borders` object and then inserts each bit flag specified +/// into it using `Borders::insert()`. +/// +/// ## Examples +/// +///``` +/// # use tui::widgets::{Block, Borders}; +/// # use tui::style::{Style, Color}; +/// # use tui::border; +/// +/// Block::default() +/// //Construct a `Borders` object and use it in place +/// .borders(border!(TOP, BOTTOM)); +/// +/// //`border!` can be called with any order of individual sides +/// let bottom_first = border!(BOTTOM, LEFT, TOP); +/// //with the ALL keyword which works as expected +/// let all = border!(ALL); +/// //or with nothing to return a `Borders::NONE' bitflag. +/// let none = border!(NONE); +/// +///``` +#[cfg(feature = "macros")] +#[macro_export] +macro_rules! border { + ( $($b:tt), +) => {{ + let mut border = Borders::empty(); + $( + border.insert(Borders::$b); + )* + border + }}; + () =>{ + Borders::NONE + } +} diff --git a/tests/border_macro.rs b/tests/border_macro.rs new file mode 100644 index 00000000..fc8cc8cd --- /dev/null +++ b/tests/border_macro.rs @@ -0,0 +1,19 @@ +#![cfg(feature = "macros")] +use ratatui::{border, widgets::Borders}; + +#[test] +fn border_empty_test() { + let empty = Borders::NONE; + assert_eq!(empty, border!()); +} +#[test] +fn border_all_test() { + let all = Borders::ALL; + assert_eq!(all, border!(ALL)); + assert_eq!(all, border!(TOP, BOTTOM, LEFT, RIGHT)); +} +#[test] +fn border_left_right_test() { + let left_right = Borders::from_bits(Borders::LEFT.bits() | Borders::RIGHT.bits()); + assert_eq!(left_right, Some(border!(RIGHT, LEFT))); +}