1 | //! Implementation of [`SmartDisplay`] for various types. |
2 | |
3 | #[cfg (feature = "alloc" )] |
4 | use alloc::borrow::{Cow, ToOwned}; |
5 | #[cfg (feature = "alloc" )] |
6 | use alloc::boxed::Box; |
7 | #[cfg (feature = "alloc" )] |
8 | use alloc::rc::Rc; |
9 | #[cfg (feature = "alloc" )] |
10 | use alloc::string::String; |
11 | #[cfg (feature = "alloc" )] |
12 | use alloc::sync::Arc; |
13 | use core::cell::{Ref, RefMut}; |
14 | use core::cmp::min; |
15 | use core::convert::Infallible; |
16 | use core::fmt::{self, Display, Formatter}; |
17 | use core::num::Wrapping; |
18 | use core::pin::Pin; |
19 | |
20 | use crate::smart_display::{FormatterOptions, Metadata, SmartDisplay}; |
21 | |
22 | impl SmartDisplay for Infallible { |
23 | type Metadata = Self; |
24 | |
25 | #[inline ] |
26 | fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> { |
27 | match *self {} |
28 | } |
29 | |
30 | #[inline ] |
31 | fn fmt(&self, _: &mut Formatter<'_>) -> fmt::Result { |
32 | match *self {} |
33 | } |
34 | } |
35 | |
36 | impl SmartDisplay for bool { |
37 | type Metadata = (); |
38 | |
39 | #[inline ] |
40 | fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> { |
41 | Metadata::new(unpadded_width:if *self { 4 } else { 5 }, self, ()) |
42 | } |
43 | |
44 | #[inline ] |
45 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
46 | Display::fmt(self, f) |
47 | } |
48 | } |
49 | |
50 | impl SmartDisplay for str { |
51 | type Metadata = (); |
52 | |
53 | #[inline ] |
54 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
55 | Metadata::new( |
56 | unpadded_width:match f.precision() { |
57 | Some(max_len) => min(self.len(), max_len), |
58 | None => self.len(), |
59 | }, |
60 | self, |
61 | (), |
62 | ) |
63 | } |
64 | |
65 | #[inline ] |
66 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
67 | Display::fmt(self, f) |
68 | } |
69 | } |
70 | |
71 | #[cfg (feature = "alloc" )] |
72 | impl SmartDisplay for String { |
73 | type Metadata = (); |
74 | |
75 | #[inline ] |
76 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
77 | (**self).metadata(f).reuse() |
78 | } |
79 | |
80 | #[inline ] |
81 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
82 | Display::fmt(self, f) |
83 | } |
84 | } |
85 | |
86 | #[cfg (feature = "alloc" )] |
87 | impl<'a, B, O> SmartDisplay for Cow<'a, B> |
88 | where |
89 | B: SmartDisplay + ToOwned<Owned = O> + ?Sized, |
90 | O: SmartDisplay<Metadata = B::Metadata> + 'a, |
91 | { |
92 | type Metadata = B::Metadata; |
93 | |
94 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
95 | match *self { |
96 | Cow::Borrowed(ref b) => b.metadata(f).reuse(), |
97 | Cow::Owned(ref o) => o.metadata(f).reuse(), |
98 | } |
99 | } |
100 | |
101 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
102 | Display::fmt(self, f) |
103 | } |
104 | } |
105 | |
106 | impl<T> SmartDisplay for Pin<&T> |
107 | where |
108 | T: SmartDisplay + ?Sized, |
109 | { |
110 | type Metadata = T::Metadata; |
111 | |
112 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
113 | self.get_ref().metadata(f).reuse() |
114 | } |
115 | |
116 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
117 | SmartDisplay::fmt(self.get_ref(), f) |
118 | } |
119 | } |
120 | |
121 | impl<T> SmartDisplay for &T |
122 | where |
123 | T: SmartDisplay + ?Sized, |
124 | { |
125 | type Metadata = T::Metadata; |
126 | |
127 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
128 | (**self).metadata(f).reuse() |
129 | } |
130 | |
131 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
132 | SmartDisplay::fmt(*self, f) |
133 | } |
134 | } |
135 | |
136 | impl<T> SmartDisplay for &mut T |
137 | where |
138 | T: SmartDisplay + ?Sized, |
139 | { |
140 | type Metadata = T::Metadata; |
141 | |
142 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
143 | (**self).metadata(f).reuse() |
144 | } |
145 | |
146 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
147 | SmartDisplay::fmt(*self, f) |
148 | } |
149 | } |
150 | |
151 | impl<T> SmartDisplay for Ref<'_, T> |
152 | where |
153 | T: SmartDisplay + ?Sized, |
154 | { |
155 | type Metadata = T::Metadata; |
156 | |
157 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
158 | (**self).metadata(f).reuse() |
159 | } |
160 | |
161 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
162 | SmartDisplay::fmt(&**self, f) |
163 | } |
164 | } |
165 | |
166 | impl<T> SmartDisplay for RefMut<'_, T> |
167 | where |
168 | T: SmartDisplay + ?Sized, |
169 | { |
170 | type Metadata = T::Metadata; |
171 | |
172 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
173 | (**self).metadata(f).reuse() |
174 | } |
175 | |
176 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
177 | SmartDisplay::fmt(&**self, f) |
178 | } |
179 | } |
180 | |
181 | impl<T> SmartDisplay for Wrapping<T> |
182 | where |
183 | T: SmartDisplay, |
184 | { |
185 | type Metadata = T::Metadata; |
186 | |
187 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
188 | self.0.metadata(f).reuse() |
189 | } |
190 | |
191 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
192 | SmartDisplay::fmt(&self.0, f) |
193 | } |
194 | } |
195 | |
196 | #[cfg (feature = "alloc" )] |
197 | impl<T> SmartDisplay for Rc<T> |
198 | where |
199 | T: SmartDisplay + ?Sized, |
200 | { |
201 | type Metadata = T::Metadata; |
202 | |
203 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
204 | (**self).metadata(f).reuse() |
205 | } |
206 | |
207 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
208 | SmartDisplay::fmt(&**self, f) |
209 | } |
210 | } |
211 | |
212 | #[cfg (feature = "alloc" )] |
213 | impl<T> SmartDisplay for Arc<T> |
214 | where |
215 | T: SmartDisplay + ?Sized, |
216 | { |
217 | type Metadata = T::Metadata; |
218 | |
219 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
220 | (**self).metadata(f).reuse() |
221 | } |
222 | |
223 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
224 | SmartDisplay::fmt(&**self, f) |
225 | } |
226 | } |
227 | |
228 | #[cfg (feature = "alloc" )] |
229 | impl<T> SmartDisplay for Box<T> |
230 | where |
231 | T: SmartDisplay + ?Sized, |
232 | { |
233 | type Metadata = T::Metadata; |
234 | |
235 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
236 | (**self).metadata(f).reuse() |
237 | } |
238 | |
239 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
240 | SmartDisplay::fmt(&**self, f) |
241 | } |
242 | } |
243 | |
244 | /// Implement [`SmartDisplay`] for unsigned integers. |
245 | macro_rules! impl_uint { |
246 | ($($t:ty)*) => {$( |
247 | impl SmartDisplay for $t { |
248 | type Metadata = (); |
249 | |
250 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
251 | let mut width = self.checked_ilog10().map_or(1, |n| n as usize + 1); |
252 | if f.sign_plus() || f.sign_minus() { |
253 | width += 1; |
254 | } |
255 | Metadata::new(width, self, ()) |
256 | } |
257 | |
258 | #[inline] |
259 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
260 | Display::fmt(self, f) |
261 | } |
262 | } |
263 | )*}; |
264 | } |
265 | |
266 | impl_uint![u8 u16 u32 u64 u128 usize]; |
267 | |
268 | /// Implement [`SmartDisplay`] for signed integers. |
269 | macro_rules! impl_int { |
270 | ($($t:ty)*) => {$( |
271 | impl SmartDisplay for $t { |
272 | type Metadata = (); |
273 | |
274 | fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> { |
275 | let mut width = if f.sign_plus() || *self < 0 { 1 } else { 0 }; |
276 | width += self.unsigned_abs().checked_ilog10().map_or(1, |n| n as usize + 1); |
277 | Metadata::new(width, self, ()) |
278 | } |
279 | |
280 | #[inline] |
281 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
282 | Display::fmt(self, f) |
283 | } |
284 | } |
285 | )*}; |
286 | } |
287 | |
288 | impl_int![i8 i16 i32 i64 i128 isize]; |
289 | |
290 | impl SmartDisplay for char { |
291 | type Metadata = (); |
292 | |
293 | fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> { |
294 | let mut buf: [u8; 4] = [0; 4]; |
295 | let c: &mut str = self.encode_utf8(&mut buf); |
296 | |
297 | Metadata::new(unpadded_width:c.len(), self, ()) |
298 | } |
299 | |
300 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
301 | Display::fmt(self, f) |
302 | } |
303 | } |
304 | |