1//! This module contains a [`Padding`] setting of a cell on a [`Table`].
2//!
3//! # Example
4//!
5#![cfg_attr(feature = "std", doc = "```")]
6#![cfg_attr(not(feature = "std"), doc = "```ignore")]
7//! use tabled::{Table, settings::{Padding, Style, Modify, object::Cell}};
8//!
9//! let table = Table::new("2022".chars())
10//! .with(Style::modern())
11//! .with(Modify::new((2, 0)).with(Padding::new(1, 1, 2, 2)))
12//! .to_string();
13//!
14//! assert_eq!(
15//! table,
16//! concat!(
17//! "┌──────┐\n",
18//! "│ char │\n",
19//! "├──────┤\n",
20//! "│ 2 │\n",
21//! "├──────┤\n",
22//! "│ │\n",
23//! "│ │\n",
24//! "│ 0 │\n",
25//! "│ │\n",
26//! "│ │\n",
27//! "├──────┤\n",
28//! "│ 2 │\n",
29//! "├──────┤\n",
30//! "│ 2 │\n",
31//! "└──────┘",
32//! ),
33//! );
34//! ```
35//!
36//! [`Table`]: crate::Table
37
38use crate::{
39 grid::{
40 color::StaticColor,
41 config::{CompactConfig, CompactMultilineConfig},
42 config::{Indent, Sides},
43 },
44 settings::TableOption,
45};
46
47#[cfg(feature = "std")]
48use crate::grid::{color::AnsiColor, config::ColoredConfig, config::Entity};
49#[cfg(feature = "std")]
50use crate::settings::CellOption;
51
52/// Padding is responsible for a left/right/top/bottom inner indent of a particular cell.
53///
54#[cfg_attr(feature = "std", doc = "```")]
55#[cfg_attr(not(feature = "std"), doc = "```ignore")]
56/// # use tabled::{settings::{Style, Padding, object::Rows, Modify}, Table};
57/// # let data: Vec<&'static str> = Vec::new();
58/// let table = Table::new(&data).with(Modify::new(Rows::single(0)).with(Padding::new(0, 0, 1, 1).fill('>', '<', '^', 'V')));
59/// ```
60#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
61pub struct Padding<C = StaticColor> {
62 indent: Sides<Indent>,
63 colors: Option<Sides<C>>,
64}
65
66impl Padding {
67 /// Construct's an Padding object.
68 ///
69 /// It uses space(' ') as a default fill character.
70 /// To set a custom character you can use [`Padding::fill`] function.
71 pub const fn new(left: usize, right: usize, top: usize, bottom: usize) -> Self {
72 Self {
73 indent: Sides::new(
74 Indent::spaced(left),
75 Indent::spaced(right),
76 Indent::spaced(top),
77 Indent::spaced(bottom),
78 ),
79 colors: None,
80 }
81 }
82
83 /// Construct's an Padding object with all sides set to 0.
84 ///
85 /// It uses space(' ') as a default fill character.
86 /// To set a custom character you can use [`Padding::fill`] function.
87 pub const fn zero() -> Self {
88 Self::new(0, 0, 0, 0)
89 }
90}
91
92impl<Color> Padding<Color> {
93 /// The function, sets a characters for the padding on an each side.
94 pub const fn fill(mut self, left: char, right: char, top: char, bottom: char) -> Self {
95 self.indent.left.fill = left;
96 self.indent.right.fill = right;
97 self.indent.top.fill = top;
98 self.indent.bottom.fill = bottom;
99 self
100 }
101
102 /// The function, sets a characters for the padding on an each side.
103 pub fn colorize<C>(self, left: C, right: C, top: C, bottom: C) -> Padding<C> {
104 Padding {
105 indent: self.indent,
106 colors: Some(Sides::new(left, right, top, bottom)),
107 }
108 }
109}
110
111#[cfg(feature = "std")]
112impl<R, C> CellOption<R, ColoredConfig> for Padding<C>
113where
114 C: Into<AnsiColor<'static>> + Clone,
115{
116 fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
117 let indent: Sides = self.indent;
118 let pad: Sides = Sides::new(indent.left, indent.right, indent.top, indent.bottom);
119 cfg.set_padding(entity, padding:pad);
120
121 if let Some(colors: &Sides) = &self.colors {
122 let pad: Sides>> = Sides::new(
123 left:Some(colors.left.clone().into()),
124 right:Some(colors.right.clone().into()),
125 top:Some(colors.top.clone().into()),
126 bottom:Some(colors.bottom.clone().into()),
127 );
128 cfg.set_padding_color(entity, padding:pad);
129 }
130 }
131}
132
133#[cfg(feature = "std")]
134impl<R, D, C> TableOption<R, D, ColoredConfig> for Padding<C>
135where
136 C: Into<AnsiColor<'static>> + Clone,
137{
138 fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
139 <Self as CellOption<R, ColoredConfig>>::change(self, records, cfg, Entity::Global)
140 }
141}
142
143impl<R, D, C> TableOption<R, D, CompactConfig> for Padding<C>
144where
145 C: Into<StaticColor> + Clone,
146{
147 fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
148 *cfg = cfg.set_padding(self.indent);
149
150 if let Some(c: Sides) = self.colors {
151 let colors: Sides = Sides::new(left:c.left.into(), right:c.right.into(), top:c.top.into(), bottom:c.bottom.into());
152 *cfg = cfg.set_padding_color(colors);
153 }
154 }
155}
156
157impl<R, D, C> TableOption<R, D, CompactMultilineConfig> for Padding<C>
158where
159 C: Into<StaticColor> + Clone,
160{
161 fn change(self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
162 self.change(records, cfg:cfg.as_mut(), dimension)
163 }
164}
165