1#[cfg(feature = "alloc")]
4use alloc::borrow::{Cow, ToOwned};
5#[cfg(feature = "alloc")]
6use alloc::boxed::Box;
7#[cfg(feature = "alloc")]
8use alloc::rc::Rc;
9#[cfg(feature = "alloc")]
10use alloc::string::String;
11#[cfg(feature = "alloc")]
12use alloc::sync::Arc;
13use core::cell::{Ref, RefMut};
14use core::cmp::min;
15use core::convert::Infallible;
16use core::fmt::{self, Display, Formatter};
17use core::num::Wrapping;
18use core::pin::Pin;
19
20use crate::smart_display::{FormatterOptions, Metadata, SmartDisplay};
21
22impl 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
36impl SmartDisplay for bool {
37 type Metadata = ();
38
39 #[inline]
40 fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
41 Metadata::new(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
50impl SmartDisplay for str {
51 type Metadata = ();
52
53 #[inline]
54 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
55 Metadata::new(
56 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")]
72impl 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")]
87impl<'a, B, O> SmartDisplay for Cow<'a, B>
88where
89 B: SmartDisplay + ToOwned<Owned = O> + ?Sized,
90 O: SmartDisplay<Metadata = B::Metadata> + 'a,
91{
92 type Metadata = B::Metadata;
93
94 #[inline]
95 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
96 match *self {
97 Cow::Borrowed(ref b) => b.metadata(f).reuse(),
98 Cow::Owned(ref o) => o.metadata(f).reuse(),
99 }
100 }
101
102 #[inline]
103 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
104 Display::fmt(self, f)
105 }
106}
107
108impl<T> SmartDisplay for Pin<&T>
109where
110 T: SmartDisplay + ?Sized,
111{
112 type Metadata = T::Metadata;
113
114 #[inline]
115 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
116 self.get_ref().metadata(f).reuse()
117 }
118
119 #[inline]
120 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
121 SmartDisplay::fmt(self.get_ref(), f)
122 }
123}
124
125impl<T> SmartDisplay for &T
126where
127 T: SmartDisplay + ?Sized,
128{
129 type Metadata = T::Metadata;
130
131 #[inline]
132 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
133 (**self).metadata(f).reuse()
134 }
135
136 #[inline]
137 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
138 SmartDisplay::fmt(*self, f)
139 }
140}
141
142impl<T> SmartDisplay for &mut T
143where
144 T: SmartDisplay + ?Sized,
145{
146 type Metadata = T::Metadata;
147
148 #[inline]
149 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
150 (**self).metadata(f).reuse()
151 }
152
153 #[inline]
154 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
155 SmartDisplay::fmt(*self, f)
156 }
157}
158
159impl<T> SmartDisplay for Ref<'_, T>
160where
161 T: SmartDisplay + ?Sized,
162{
163 type Metadata = T::Metadata;
164
165 #[inline]
166 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
167 (**self).metadata(f).reuse()
168 }
169
170 #[inline]
171 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
172 SmartDisplay::fmt(&**self, f)
173 }
174}
175
176impl<T> SmartDisplay for RefMut<'_, T>
177where
178 T: SmartDisplay + ?Sized,
179{
180 type Metadata = T::Metadata;
181
182 #[inline]
183 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
184 (**self).metadata(f).reuse()
185 }
186
187 #[inline]
188 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
189 SmartDisplay::fmt(&**self, f)
190 }
191}
192
193impl<T> SmartDisplay for Wrapping<T>
194where
195 T: SmartDisplay,
196{
197 type Metadata = T::Metadata;
198
199 #[inline]
200 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
201 self.0.metadata(f).reuse()
202 }
203
204 #[inline]
205 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
206 SmartDisplay::fmt(&self.0, f)
207 }
208}
209
210#[cfg(feature = "alloc")]
211impl<T> SmartDisplay for Rc<T>
212where
213 T: SmartDisplay + ?Sized,
214{
215 type Metadata = T::Metadata;
216
217 #[inline]
218 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
219 (**self).metadata(f).reuse()
220 }
221
222 #[inline]
223 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
224 SmartDisplay::fmt(&**self, f)
225 }
226}
227
228#[cfg(feature = "alloc")]
229impl<T> SmartDisplay for Arc<T>
230where
231 T: SmartDisplay + ?Sized,
232{
233 type Metadata = T::Metadata;
234
235 #[inline]
236 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
237 (**self).metadata(f).reuse()
238 }
239
240 #[inline]
241 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
242 SmartDisplay::fmt(&**self, f)
243 }
244}
245
246#[cfg(feature = "alloc")]
247impl<T> SmartDisplay for Box<T>
248where
249 T: SmartDisplay + ?Sized,
250{
251 type Metadata = T::Metadata;
252
253 #[inline]
254 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
255 (**self).metadata(f).reuse()
256 }
257
258 #[inline]
259 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
260 SmartDisplay::fmt(&**self, f)
261 }
262}
263
264macro_rules! impl_uint {
266 ($($t:ty)*) => {$(
267 impl SmartDisplay for $t {
268 type Metadata = ();
269
270 #[inline]
271 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
272 let mut width = self.checked_ilog10().map_or(1, |n| n as usize + 1);
273 if f.sign_plus() || f.sign_minus() {
274 width += 1;
275 }
276 Metadata::new(width, self, ())
277 }
278
279 #[inline]
280 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
281 Display::fmt(self, f)
282 }
283 }
284 )*};
285}
286
287impl_uint![u8 u16 u32 u64 u128 usize];
288
289macro_rules! impl_int {
291 ($($t:ty)*) => {$(
292 impl SmartDisplay for $t {
293 type Metadata = ();
294
295 #[inline]
296 fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self> {
297 let mut width = if f.sign_plus() || *self < 0 { 1 } else { 0 };
298 width += self.unsigned_abs().checked_ilog10().map_or(1, |n| n as usize + 1);
299 Metadata::new(width, self, ())
300 }
301
302 #[inline]
303 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
304 Display::fmt(self, f)
305 }
306 }
307 )*};
308}
309
310impl_int![i8 i16 i32 i64 i128 isize];
311
312impl SmartDisplay for char {
313 type Metadata = ();
314
315 #[inline]
316 fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
317 let mut buf = [0; 4];
318 let c = self.encode_utf8(&mut buf);
319
320 Metadata::new(c.len(), self, ())
321 }
322
323 #[inline]
324 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
325 Display::fmt(self, f)
326 }
327}