powerfmt/
smart_display_impls.rs

1//! Implementation of [`SmartDisplay`] for various types.
2
3#[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    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
106impl<T> SmartDisplay for Pin<&T>
107where
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
121impl<T> SmartDisplay for &T
122where
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
136impl<T> SmartDisplay for &mut T
137where
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
151impl<T> SmartDisplay for Ref<'_, T>
152where
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
166impl<T> SmartDisplay for RefMut<'_, T>
167where
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
181impl<T> SmartDisplay for Wrapping<T>
182where
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")]
197impl<T> SmartDisplay for Rc<T>
198where
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")]
213impl<T> SmartDisplay for Arc<T>
214where
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")]
229impl<T> SmartDisplay for Box<T>
230where
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.
245macro_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
266impl_uint![u8 u16 u32 u64 u128 usize];
267
268/// Implement [`SmartDisplay`] for signed integers.
269macro_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
288impl_int![i8 i16 i32 i64 i128 isize];
289
290impl SmartDisplay for char {
291    type Metadata = ();
292
293    fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
294        let mut buf = [0; 4];
295        let c = self.encode_utf8(&mut buf);
296
297        Metadata::new(c.len(), self, ())
298    }
299
300    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
301        Display::fmt(self, f)
302    }
303}