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 | |
38 | use crate::{ |
39 | grid::{ |
40 | color::StaticColor, |
41 | config::{CompactConfig, CompactMultilineConfig}, |
42 | config::{Indent, Sides}, |
43 | }, |
44 | settings::TableOption, |
45 | }; |
46 | |
47 | #[cfg (feature = "std" )] |
48 | use crate::grid::{color::AnsiColor, config::ColoredConfig, config::Entity}; |
49 | #[cfg (feature = "std" )] |
50 | use 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)] |
61 | pub struct Padding<C = StaticColor> { |
62 | indent: Sides<Indent>, |
63 | colors: Option<Sides<C>>, |
64 | } |
65 | |
66 | impl 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 | |
92 | impl<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" )] |
112 | impl<R, C> CellOption<R, ColoredConfig> for Padding<C> |
113 | where |
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" )] |
134 | impl<R, D, C> TableOption<R, D, ColoredConfig> for Padding<C> |
135 | where |
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 | |
143 | impl<R, D, C> TableOption<R, D, CompactConfig> for Padding<C> |
144 | where |
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 | |
157 | impl<R, D, C> TableOption<R, D, CompactMultilineConfig> for Padding<C> |
158 | where |
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 | |