zero_copy_pads/pad.rs
1use crate::{Unit, Width};
2use core::fmt::{Display, Error, Formatter};
3use fmt_iter::repeat;
4
5/// Pad a value knowing the number of blocks.
6///
7/// Values that implement this trait are to be passed
8/// to `pad` field of [`PaddedValue`](crate::PaddedValue)
9/// or [`PaddedColumn`](crate::PaddedColumn).
10pub trait Pad<Value: Width, PadBlock: Display> {
11 /// Pad a value knowing the number of blocks.
12 fn fmt(
13 &self,
14 formatter: &mut Formatter<'_>,
15 value: &Value,
16 pad_block: &PadBlock,
17 pad_width: usize,
18 ) -> Result<(), Error>;
19}
20
21impl<Value, PadBlock, X> Pad<Value, PadBlock> for &X
22where
23 Value: Width,
24 PadBlock: Display,
25 X: Pad<Value, PadBlock> + Sized,
26{
27 fn fmt(
28 &self,
29 formatter: &mut Formatter<'_>,
30 value: &Value,
31 pad_block: &PadBlock,
32 pad_width: usize,
33 ) -> Result<(), Error> {
34 X::fmt(*self, formatter, value, pad_block, pad_width)
35 }
36}
37
38/// All pre-defined zero-sized [`Pad`] types in this [crate] implement this trait.
39pub trait UnitPad<Value: Width, PadBlock: Display>: Unit + Pad<Value, PadBlock> {}
40
41macro_rules! unit_pad {
42 ($name:ident) => {
43 impl Unit for $name {
44 const VALUE: Self = $name;
45 }
46
47 impl<Value: Width, PadBlock: Display> UnitPad<Value, PadBlock> for $name {}
48 };
49}
50
51/// Pad to the right, content to the left.
52///
53/// **Example:**
54///
55/// ```
56/// # use pretty_assertions::assert_eq;
57/// use zero_copy_pads::{AlignLeft, PaddedValue, PanicOnExcess};
58/// let padded_value = PaddedValue {
59/// pad: AlignLeft,
60/// value: "abcdef",
61/// pad_block: '-',
62/// total_width: 9,
63/// handle_excess: PanicOnExcess,
64/// };
65/// assert_eq!(padded_value.to_string(), "abcdef---");
66/// ```
67#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
68pub struct AlignLeft;
69unit_pad!(AlignLeft);
70
71impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignLeft {
72 fn fmt(
73 &self,
74 formatter: &mut Formatter<'_>,
75 value: &Value,
76 pad_block: &PadBlock,
77 pad_width: usize,
78 ) -> Result<(), Error> {
79 let pad = repeat(pad_block, pad_width);
80 write!(formatter, "{}{}", value, pad)
81 }
82}
83
84/// Pad to the left, content to the right.
85///
86/// **Example:**
87///
88/// ```
89/// # use pretty_assertions::assert_eq;
90/// use zero_copy_pads::{AlignRight, PaddedValue, PanicOnExcess};
91/// let padded_value = PaddedValue {
92/// pad: AlignRight,
93/// value: "abcdef",
94/// pad_block: '-',
95/// total_width: 9,
96/// handle_excess: PanicOnExcess,
97/// };
98/// assert_eq!(padded_value.to_string(), "---abcdef");
99/// ```
100#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
101pub struct AlignRight;
102unit_pad!(AlignRight);
103
104impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignRight {
105 fn fmt(
106 &self,
107 formatter: &mut Formatter<'_>,
108 value: &Value,
109 pad_block: &PadBlock,
110 pad_width: usize,
111 ) -> Result<(), Error> {
112 let pad = repeat(pad_block, pad_width);
113 write!(formatter, "{}{}", pad, value)
114 }
115}
116
117/// Pad to both sides, place content in the middle, but shift to the left one
118/// block if it can't be exactly central.
119///
120/// **Example:**
121///
122/// ```
123/// # #[cfg(feature = "std")] fn main() {
124/// # use pretty_assertions::assert_eq;
125/// use zero_copy_pads::{AlignCenterLeft, PaddedColumn, PanicOnExcess};
126/// let values = [
127/// "Rust", "C", "C++", "C#", "JavaScript",
128/// "TypeScript", "Java", "Kotlin", "Go",
129/// ];
130/// let padded_column = PaddedColumn {
131/// pad: AlignCenterLeft,
132/// values: values.iter(),
133/// pad_block: '-',
134/// };
135/// let padded_values: Vec<_> = padded_column
136/// .into_iter()
137/// .map(|x| x.to_string())
138/// .collect();
139/// let expected = [
140/// "---Rust---", "----C-----", "---C++----",
141/// "----C#----", "JavaScript", "TypeScript",
142/// "---Java---", "--Kotlin--", "----Go----",
143/// ];
144/// assert_eq!(padded_values, expected);
145/// # }
146/// # #[cfg(not(feature = "std"))] fn main() {}
147/// ```
148#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
149pub struct AlignCenterLeft;
150unit_pad!(AlignCenterLeft);
151
152impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignCenterLeft {
153 fn fmt(
154 &self,
155 formatter: &mut Formatter<'_>,
156 value: &Value,
157 pad_block: &PadBlock,
158 pad_width: usize,
159 ) -> Result<(), Error> {
160 let pad = repeat(pad_block, pad_width >> 1);
161 let remainder = repeat(pad_block, pad_width & 1);
162 write!(formatter, "{}{}{}{}", pad, value, pad, remainder)
163 }
164}
165
166/// Pad to both sides, place content in the middle, but shift to the right one
167/// block if it can't be exactly central.
168///
169/// **Example:**
170///
171/// ```
172/// # #[cfg(feature = "std")] fn main() {
173/// # use pretty_assertions::assert_eq;
174/// use zero_copy_pads::{AlignCenterRight, PaddedColumn, PanicOnExcess};
175/// let values = [
176/// "Rust", "C", "C++", "C#", "JavaScript",
177/// "TypeScript", "Java", "Kotlin", "Go",
178/// ];
179/// let padded_column = PaddedColumn {
180/// pad: AlignCenterRight,
181/// values: values.iter(),
182/// pad_block: '-',
183/// };
184/// let padded_values: Vec<_> = padded_column
185/// .into_iter()
186/// .map(|x| x.to_string())
187/// .collect();
188/// let expected = [
189/// "---Rust---", "-----C----", "----C++---",
190/// "----C#----", "JavaScript", "TypeScript",
191/// "---Java---", "--Kotlin--", "----Go----",
192/// ];
193/// assert_eq!(padded_values, expected);
194/// # }
195/// # #[cfg(not(feature = "std"))] fn main() {}
196/// ```
197#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
198pub struct AlignCenterRight;
199unit_pad!(AlignCenterRight);
200
201impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignCenterRight {
202 fn fmt(
203 &self,
204 formatter: &mut Formatter<'_>,
205 value: &Value,
206 pad_block: &PadBlock,
207 pad_width: usize,
208 ) -> Result<(), Error> {
209 let pad = repeat(pad_block, pad_width >> 1);
210 let remainder = repeat(pad_block, pad_width & 1);
211 write!(formatter, "{}{}{}{}", pad, remainder, value, pad)
212 }
213}