feat(border): add border! macro for easy bitflag manipulation (#11)

Adds a `border!` macro that takes TOP, BOTTOM, LEFT, RIGHT, and ALL and
returns a Borders object. An empty `border!()` call returns
Borders::NONE

This is gated behind a `macros` feature flag to ensure short build
times. To enable, add the following to your `Cargo.toml`:

```toml
ratatui = { version = 0.21.0, features = ["macros"] }
```

Co-authored-by: C-Jameson <booksncode@gmail.com>
This commit is contained in:
Orhun Parmaksız 2023-05-22 00:26:39 +02:00 committed by GitHub
parent fa02cf0f2b
commit ef8bc7c5a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 3 deletions

View file

@ -21,6 +21,7 @@ rust-version = "1.65.0"
default = ["crossterm"] default = ["crossterm"]
all-widgets = ["widget-calendar"] all-widgets = ["widget-calendar"]
widget-calendar = ["time"] widget-calendar = ["time"]
macros = []
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

View file

@ -118,15 +118,15 @@ args = [
] ]
[tasks.test-crossterm] [tasks.test-crossterm]
env = { TUI_FEATURES = "serde,crossterm,all-widgets" } env = { TUI_FEATURES = "serde,crossterm,all-widgets,macros" }
run_task = "test" run_task = "test"
[tasks.test-termion] [tasks.test-termion]
env = { TUI_FEATURES = "serde,termion,all-widgets" } env = { TUI_FEATURES = "serde,termion,all-widgets,macros" }
run_task = "test" run_task = "test"
[tasks.test-termwiz] [tasks.test-termwiz]
env = { TUI_FEATURES = "serde,termwiz,all-widgets" } env = { TUI_FEATURES = "serde,termwiz,all-widgets,macros" }
run_task = "test" run_task = "test"
[tasks.test] [tasks.test]

View file

@ -185,3 +185,41 @@ pub trait StatefulWidget {
type State; type State;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::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
}
}

19
tests/border_macro.rs Normal file
View file

@ -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)));
}