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 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
244macro_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
268macro_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}