smart_format/combinator/
pad.rs1use core::fmt;
2
3use smart_string::DisplayExt;
4
5pub struct PadRight<T> {
10 inner: T,
11 width: usize,
12 fill: char,
13}
14
15impl<T> PadRight<T> {
16 pub(crate) fn new(inner: T, width: usize, fill: char) -> Self {
17 PadRight { inner, width, fill }
18 }
19}
20
21impl<T: fmt::Display> fmt::Display for PadRight<T> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 use fmt::Write;
24
25 let mut char_count: usize = 0;
26
27 self.inner.format_with(|s: Option<&str>| {
28 let Some(s) = s else { return Ok(()) };
29 char_count += s.chars().count();
30 f.write_str(s)
31 })?;
32
33 for _ in char_count..self.width {
34 f.write_char(self.fill)?;
35 }
36
37 Ok(())
38 }
39}
40
41pub struct PadLeft<T> {
55 inner: T,
56 width: usize,
57 fill: char,
58}
59
60impl<T> PadLeft<T> {
61 pub(crate) fn new(inner: T, width: usize, fill: char) -> Self {
62 PadLeft { inner, width, fill }
63 }
64}
65
66impl<T: fmt::Display> fmt::Display for PadLeft<T> {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 use fmt::Write;
69
70 let mut char_count: usize = 0;
72 self.inner.format_with(|s: Option<&str>| {
73 if let Some(s) = s {
74 char_count += s.chars().count();
75 }
76 Ok(())
77 })?;
78
79 for _ in char_count..self.width {
81 f.write_char(self.fill)?;
82 }
83
84 self.inner.fmt(f)
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use crate::combinator::SmartFormat;
92
93 #[test]
96 fn pad_right_shorter() {
97 assert_eq!("hi...", "hi".display_pad_right(5, '.').to_string());
98 }
99
100 #[test]
101 fn pad_right_exact() {
102 assert_eq!("hello", "hello".display_pad_right(5, '.').to_string());
103 }
104
105 #[test]
106 fn pad_right_longer() {
107 assert_eq!("hello!", "hello!".display_pad_right(5, '.').to_string());
108 }
109
110 #[test]
111 fn pad_right_empty() {
112 assert_eq!(".....", "".display_pad_right(5, '.').to_string());
113 }
114
115 #[test]
116 fn pad_right_zero_width() {
117 assert_eq!("hello", "hello".display_pad_right(0, '.').to_string());
118 }
119
120 #[test]
121 fn pad_right_unicode() {
122 assert_eq!("АБ...", "АБ".display_pad_right(5, '.').to_string());
124 }
125
126 #[test]
127 fn pad_right_unicode_fill() {
128 assert_eq!("hi═══", "hi".display_pad_right(5, '═').to_string());
129 }
130
131 #[test]
134 fn pad_left_shorter() {
135 assert_eq!("...hi", "hi".display_pad_left(5, '.').to_string());
136 }
137
138 #[test]
139 fn pad_left_exact() {
140 assert_eq!("hello", "hello".display_pad_left(5, '.').to_string());
141 }
142
143 #[test]
144 fn pad_left_longer() {
145 assert_eq!("hello!", "hello!".display_pad_left(5, '.').to_string());
146 }
147
148 #[test]
149 fn pad_left_empty() {
150 assert_eq!(".....", "".display_pad_left(5, '.').to_string());
151 }
152
153 #[test]
154 fn pad_left_zero_width() {
155 assert_eq!("hello", "hello".display_pad_left(0, '.').to_string());
156 }
157
158 #[test]
159 fn pad_left_unicode() {
160 assert_eq!("...АБ", "АБ".display_pad_left(5, '.').to_string());
161 }
162
163 #[test]
164 fn pad_left_number() {
165 assert_eq!("007", 7.display_pad_left(3, '0').to_string());
166 }
167
168 #[test]
169 fn pad_left_unicode_fill() {
170 assert_eq!("═══hi", "hi".display_pad_left(5, '═').to_string());
171 }
172}