Skip to main content

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    #[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
264/// Implement [`SmartDisplay`] for unsigned integers.
265macro_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
289/// Implement [`SmartDisplay`] for signed integers.
290macro_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}