Coverage Report

Created: 2025-07-02 06:18

/rust/registry/src/index.crates.io-6f17d22bba15001f/powerfmt-0.2.0/src/smart_display.rs
Line
Count
Source (jump to first uncovered line)
1
//! Definition of [`SmartDisplay`] and its related items.
2
//!
3
//! [`SmartDisplay`] is a trait that allows authors to provide additional information to both the
4
//! formatter and other users. This information is provided in the form of a metadata type. The only
5
//! required piece of metadata is the width of the value. This is _before_ it is passed to the
6
//! formatter (i.e. it does not include any padding added by the formatter). Other information
7
//! can be stored in a custom metadata type as needed. This information may be made available to
8
//! downstream users, but it is not required.
9
//!
10
//! This module contains the [`SmartDisplay`] and associated items.
11
//!
12
//! # Example
13
//!
14
//! ```rust
15
//! use std::fmt;
16
//!
17
//! use powerfmt::ext::FormatterExt as _;
18
//! use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};
19
//!
20
//! #[derive(Debug)]
21
//! struct User {
22
//!     id: usize,
23
//! }
24
//!
25
//! // If you try to use `UserMetadata` in the `SmartDisplay` implementation, you will get a
26
//! // compiler error about a private type being used publicly. To avoid this, use this attribute to
27
//! // declare a private metadata type. You shouldn't need to worry about how this works, but be
28
//! // aware that any public fields or methods remain usable by downstream users.
29
//! #[smart_display::private_metadata]
30
//! struct UserMetadata {
31
//!     username: String,
32
//!     legal_name: String,
33
//! }
34
//!
35
//! // This attribute can be applied to `SmartDisplay` implementations. It will generate an
36
//! // implementation of `Display` that delegates to `SmartDisplay`, avoiding the need to write
37
//! // boilerplate.
38
//! #[smart_display::delegate]
39
//! impl SmartDisplay for User {
40
//!     type Metadata = UserMetadata;
41
//!
42
//!     fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
43
//!         // This could be obtained from a database, for example.
44
//!         let legal_name = "John Doe".to_owned();
45
//!         let username = "jdoe".to_owned();
46
//!
47
//!         // Note that this must be kept in sync with the implementation of `fmt_with_metadata`.
48
//!         let width = smart_display::padded_width_of!(username, " (", legal_name, ")",);
49
//!
50
//!         Metadata::new(
51
//!             width,
52
//!             self,
53
//!             UserMetadata {
54
//!                 username,
55
//!                 legal_name,
56
//!             },
57
//!         )
58
//!     }
59
//!
60
//!     // Use the now-generated metadata to format the value. Here we use the `pad_with_width`
61
//!     // method to use the alignment and desired width from the formatter.
62
//!     fn fmt_with_metadata(
63
//!         &self,
64
//!         f: &mut fmt::Formatter<'_>,
65
//!         metadata: Metadata<Self>,
66
//!     ) -> fmt::Result {
67
//!         f.pad_with_width(
68
//!             metadata.unpadded_width(),
69
//!             format_args!("{} ({})", metadata.username, metadata.legal_name),
70
//!         )
71
//!     }
72
//! }
73
//!
74
//! let user = User { id: 42 };
75
//! assert_eq!(user.to_string(), "jdoe (John Doe)");
76
//! assert_eq!(format!("{user:>20}"), "     jdoe (John Doe)");
77
//! ```
78
79
use core::cmp;
80
use core::convert::Infallible;
81
use core::fmt::{Alignment, Debug, Display, Formatter, Result};
82
use core::marker::PhantomData;
83
use core::mem::MaybeUninit;
84
use core::ops::Deref;
85
86
/// Compute the width of multiple items while optionally declaring the options for each item.
87
///
88
/// ```rust
89
/// # use powerfmt::smart_display;
90
/// let alpha = 0;
91
/// let beta = 1;
92
/// let gamma = 100;
93
///
94
/// let width = smart_display::padded_width_of!(
95
///     alpha, // use the default options
96
///     beta => width(2), // use the specified options
97
///     gamma => width(2) sign_plus(true), // use multiple options
98
/// );
99
/// assert_eq!(width, 7);
100
///
101
/// let formatted = format!("{alpha}{beta:2}{gamma:+2}");
102
/// assert_eq!(formatted.len(), width);
103
/// ```
104
///
105
/// Supported options are:
106
///
107
/// Option                      | Method called
108
/// ---                         | ---
109
/// `fill(char)`                | [`FormatterOptions::with_fill`]
110
/// `sign_plus(bool)`           | [`FormatterOptions::with_sign_plus`]
111
/// `sign_minus(bool)`          | [`FormatterOptions::with_sign_minus`]
112
/// `align(Alignment)`          | [`FormatterOptions::with_align`]
113
/// `width(usize)`              | [`FormatterOptions::with_width`]
114
/// `precision(usize)`          | [`FormatterOptions::with_precision`]
115
/// `alternate(bool)`           | [`FormatterOptions::with_alternate`]
116
/// `sign_aware_zero_pad(bool)` | [`FormatterOptions::with_sign_aware_zero_pad`]
117
///
118
/// If there are future additions to [`FormatterOptions`], they will be added to this macro as well.
119
///
120
/// Options may be provided in any order and will be called in the order they are provided. The
121
/// ordering matters if providing both `sign_plus` and `sign_minus`.
122
#[cfg(doc)]
123
#[doc(hidden)] // Don't show at crate root.
124
#[macro_export]
125
macro_rules! padded_width_of {
126
    ($($t:tt)*) => {};
127
}
128
129
#[cfg(not(doc))]
130
#[allow(missing_docs)] // This is done with `#[cfg(doc)]` to avoid showing the various rules.
131
#[macro_export]
132
macro_rules! __not_public_at_root__padded_width_of {
133
    // Base case
134
    (@inner [] [$($output:tt)+]) => { $($output)+ };
135
    (@inner [$e:expr $(, $($remaining:tt)*)?] [$($expansion:tt)+]) => {
136
        $crate::smart_display::padded_width_of!(@inner [$($($remaining)*)?] [
137
            $($expansion)+ + $crate::smart_display::Metadata::padded_width_of(
138
                &$e,
139
                $crate::smart_display::padded_width_of!(@options)
140
            )
141
        ])
142
    };
143
    (@inner
144
        [$e:expr => $($call:ident($call_expr:expr))+ $(, $($remaining:tt)*)?]
145
        [$($expansion:tt)+]
146
    ) => {
147
        $crate::smart_display::padded_width_of!(@inner [$($($remaining)*)?] [
148
            $($expansion)+ + $crate::smart_display::Metadata::padded_width_of(
149
                &$e,
150
                *$crate::smart_display::padded_width_of!(@options $($call($call_expr))+)
151
            )
152
        ])
153
    };
154
155
    // Options base case
156
    (@options_inner [] [$($output:tt)+]) => { $($output)+ };
157
    (@options_inner [fill($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
158
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
159
            $($expansion)*.with_fill($e)
160
        ])
161
    };
162
    (@options_inner [sign_plus($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
163
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
164
            $($expansion)*.with_sign_plus($e)
165
        ])
166
    };
167
    (@options_inner [sign_minus($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
168
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
169
            $($expansion)*.with_sign_minus($e)
170
        ])
171
    };
172
    (@options_inner [align($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
173
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
174
            $($expansion)*.with_align(Some($e))
175
        ])
176
    };
177
    (@options_inner [width($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
178
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
179
            $($expansion)*.with_width(Some($e))
180
        ])
181
    };
182
    (@options_inner [precision($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
183
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
184
            $($expansion)*.with_precision(Some($e))
185
        ])
186
    };
187
    (@options_inner [alternate($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
188
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
189
            $($expansion)*.with_width($e)
190
        ])
191
    };
192
    (@options_inner [sign_aware_zero_pad($e:expr) $($remaining:tt)*] [$($expansion:tt)*]) => {
193
        $crate::smart_display::padded_width_of!(@options_inner [$($remaining)*] [
194
            $($expansion)*.with_sign_aware_zero_pad($e)
195
        ])
196
    };
197
    // Options entry point
198
    (@options $($e:tt)*) => {
199
        $crate::smart_display::padded_width_of!(@options_inner [$($e)*] [
200
            $crate::smart_display::FormatterOptions::default()
201
        ])
202
    };
203
204
    // Entry point
205
    ($($t:tt)*) => {
206
        $crate::smart_display::padded_width_of!(
207
            @inner [$($t)*] [0]
208
        )
209
    };
210
}
211
212
#[cfg(not(doc))]
213
pub use __not_public_at_root__padded_width_of as padded_width_of;
214
#[cfg(doc)]
215
#[doc(inline)] // Show in this module.
216
pub use padded_width_of;
217
/// Implement [`Display`] for a type by using its implementation of [`SmartDisplay`].
218
///
219
/// This attribute is applied to the `SmartDisplay` implementation.
220
///
221
/// ```rust,no_run
222
/// # use powerfmt::smart_display::{self, SmartDisplay, Metadata, FormatterOptions};
223
/// # struct Foo;
224
/// #[smart_display::delegate]
225
/// impl SmartDisplay for Foo {
226
/// #   type Metadata = ();
227
/// #   fn metadata(&self, f: FormatterOptions) -> Metadata<Self> {
228
/// #       todo!()
229
/// #   }
230
///     // ...
231
/// }
232
/// ```
233
#[cfg(feature = "macros")]
234
pub use powerfmt_macros::smart_display_delegate as delegate;
235
/// Declare a private metadata type for `SmartDisplay`.
236
///
237
/// Use this attribute if you want to provide metadata for a type that is not public. Doing
238
/// this will avoid a compiler error about a private type being used publicly. Keep in mind
239
/// that any public fields, public methods, and trait implementations _will_ be able to be used
240
/// by downstream users.
241
///
242
/// To avoid accidentally exposing details, such as when all fields are public or if the type
243
/// is a unit struct, the type is annotated with `#[non_exhaustive]` automatically.
244
///
245
/// ```rust,no_run
246
/// # use powerfmt::smart_display;
247
/// /// Metadata for `Foo`
248
/// #[smart_display::private_metadata]
249
/// #[derive(Debug)]
250
/// pub(crate) struct FooMetadata {
251
///     pub(crate) expensive_to_calculate: usize,
252
/// }
253
/// ```
254
#[cfg(feature = "macros")]
255
pub use powerfmt_macros::smart_display_private_metadata as private_metadata;
256
257
#[derive(Debug)]
258
enum FlagBit {
259
    SignPlus,
260
    SignMinus,
261
    Alternate,
262
    SignAwareZeroPad,
263
    WidthIsInitialized,
264
    PrecisionIsInitialized,
265
}
266
267
/// Configuration for formatting.
268
///
269
/// This struct is obtained from a [`Formatter`]. It provides the same functionality as that of a
270
/// reference to a `Formatter`. However, it is not possible to construct a `Formatter`, which is
271
/// necessary for some use cases of [`SmartDisplay`]. `FormatterOptions` implements [`Default`] and
272
/// has builder methods to alleviate this.
273
#[derive(Clone, Copy)]
274
pub struct FormatterOptions {
275
    flags: u8,
276
    fill: char,
277
    align: Option<Alignment>,
278
    width: MaybeUninit<usize>,
279
    precision: MaybeUninit<usize>,
280
}
281
282
impl Debug for FormatterOptions {
283
0
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
284
0
        f.debug_struct("FormatterOptions")
285
0
            .field("fill", &self.fill)
286
0
            .field("align", &self.align())
287
0
            .field("width", &self.width())
288
0
            .field("precision", &self.precision())
289
0
            .field("sign_plus", &self.sign_plus())
290
0
            .field("sign_minus", &self.sign_minus())
291
0
            .field("alternate", &self.alternate())
292
0
            .field("sign_aware_zero_pad", &self.sign_aware_zero_pad())
293
0
            .finish()
294
0
    }
295
}
296
297
impl Default for FormatterOptions {
298
    #[inline]
299
51.3k
    fn default() -> Self {
300
51.3k
        Self {
301
51.3k
            flags: 0,
302
51.3k
            fill: ' ',
303
51.3k
            align: None,
304
51.3k
            width: MaybeUninit::uninit(),
305
51.3k
            precision: MaybeUninit::uninit(),
306
51.3k
        }
307
51.3k
    }
<powerfmt::smart_display::FormatterOptions as core::default::Default>::default
Line
Count
Source
299
46.3k
    fn default() -> Self {
300
46.3k
        Self {
301
46.3k
            flags: 0,
302
46.3k
            fill: ' ',
303
46.3k
            align: None,
304
46.3k
            width: MaybeUninit::uninit(),
305
46.3k
            precision: MaybeUninit::uninit(),
306
46.3k
        }
307
46.3k
    }
<powerfmt::smart_display::FormatterOptions as core::default::Default>::default
Line
Count
Source
299
5.00k
    fn default() -> Self {
300
5.00k
        Self {
301
5.00k
            flags: 0,
302
5.00k
            fill: ' ',
303
5.00k
            align: None,
304
5.00k
            width: MaybeUninit::uninit(),
305
5.00k
            precision: MaybeUninit::uninit(),
306
5.00k
        }
307
5.00k
    }
308
}
309
310
impl FormatterOptions {
311
    /// Sets the fill character to use whenever there is alignment.
312
    #[inline]
313
10.0k
    pub fn with_fill(&mut self, c: char) -> &mut Self {
314
10.0k
        self.fill = c;
315
10.0k
        self
316
10.0k
    }
<powerfmt::smart_display::FormatterOptions>::with_fill
Line
Count
Source
313
5.00k
    pub fn with_fill(&mut self, c: char) -> &mut Self {
314
5.00k
        self.fill = c;
315
5.00k
        self
316
5.00k
    }
<powerfmt::smart_display::FormatterOptions>::with_fill
Line
Count
Source
313
5.00k
    pub fn with_fill(&mut self, c: char) -> &mut Self {
314
5.00k
        self.fill = c;
315
5.00k
        self
316
5.00k
    }
317
318
    /// Set whether the `+` flag is specified.
319
    #[inline]
320
5.00k
    pub fn with_sign_plus(&mut self, b: bool) -> &mut Self {
321
5.00k
        if b {
322
0
            self.flags |= 1 << FlagBit::SignPlus as u8;
323
0
            self.flags &= !(1 << FlagBit::SignMinus as u8);
324
5.00k
        } else {
325
5.00k
            self.flags &= !(1 << FlagBit::SignPlus as u8);
326
5.00k
        }
327
5.00k
        self
328
5.00k
    }
329
330
    /// Set whether the `-` flag is specified.
331
    #[inline]
332
5.00k
    pub fn with_sign_minus(&mut self, b: bool) -> &mut Self {
333
5.00k
        if b {
334
0
            self.flags |= 1 << FlagBit::SignMinus as u8;
335
0
            self.flags &= !(1 << FlagBit::SignPlus as u8);
336
5.00k
        } else {
337
5.00k
            self.flags &= !(1 << FlagBit::SignMinus as u8);
338
5.00k
        }
339
5.00k
        self
340
5.00k
    }
341
342
    /// Set the flag indicating what form of alignment is requested, if any.
343
    #[inline]
344
5.00k
    pub fn with_align(&mut self, align: Option<Alignment>) -> &mut Self {
345
5.00k
        self.align = align;
346
5.00k
        self
347
5.00k
    }
348
349
    /// Set the optional integer width that the output should be.
350
    #[inline]
351
22.5k
    pub fn with_width(&mut self, width: Option<usize>) -> &mut Self {
352
22.5k
        if let Some(width) = width {
353
17.5k
            self.flags |= 1 << FlagBit::WidthIsInitialized as u8;
354
17.5k
            self.width = MaybeUninit::new(width);
355
17.5k
        } else {
356
5.00k
            self.flags &= !(1 << FlagBit::WidthIsInitialized as u8);
357
5.00k
        }
358
22.5k
        self
359
22.5k
    }
<powerfmt::smart_display::FormatterOptions>::with_width
Line
Count
Source
351
17.5k
    pub fn with_width(&mut self, width: Option<usize>) -> &mut Self {
352
17.5k
        if let Some(width) = width {
353
17.5k
            self.flags |= 1 << FlagBit::WidthIsInitialized as u8;
354
17.5k
            self.width = MaybeUninit::new(width);
355
17.5k
        } else {
356
0
            self.flags &= !(1 << FlagBit::WidthIsInitialized as u8);
357
0
        }
358
17.5k
        self
359
17.5k
    }
<powerfmt::smart_display::FormatterOptions>::with_width
Line
Count
Source
351
5.00k
    pub fn with_width(&mut self, width: Option<usize>) -> &mut Self {
352
5.00k
        if let Some(width) = width {
353
0
            self.flags |= 1 << FlagBit::WidthIsInitialized as u8;
354
0
            self.width = MaybeUninit::new(width);
355
5.00k
        } else {
356
5.00k
            self.flags &= !(1 << FlagBit::WidthIsInitialized as u8);
357
5.00k
        }
358
5.00k
        self
359
5.00k
    }
360
361
    /// Set the optional precision for numeric types. Alternatively, the maximum width for string
362
    /// types.
363
    #[inline]
364
5.00k
    pub fn with_precision(&mut self, precision: Option<usize>) -> &mut Self {
365
5.00k
        if let Some(precision) = precision {
366
0
            self.flags |= 1 << FlagBit::PrecisionIsInitialized as u8;
367
0
            self.precision = MaybeUninit::new(precision);
368
5.00k
        } else {
369
5.00k
            self.flags &= !(1 << FlagBit::PrecisionIsInitialized as u8);
370
5.00k
        }
371
5.00k
        self
372
5.00k
    }
373
374
    /// Set whether the `#` flag is specified.
375
    #[inline]
376
5.00k
    pub fn with_alternate(&mut self, b: bool) -> &mut Self {
377
5.00k
        if b {
378
0
            self.flags |= 1 << FlagBit::Alternate as u8;
379
5.00k
        } else {
380
5.00k
            self.flags &= !(1 << FlagBit::Alternate as u8);
381
5.00k
        }
382
5.00k
        self
383
5.00k
    }
384
385
    /// Set whether the `0` flag is specified.
386
    #[inline]
387
5.00k
    pub fn with_sign_aware_zero_pad(&mut self, b: bool) -> &mut Self {
388
5.00k
        if b {
389
0
            self.flags |= 1 << FlagBit::SignAwareZeroPad as u8;
390
5.00k
        } else {
391
5.00k
            self.flags &= !(1 << FlagBit::SignAwareZeroPad as u8);
392
5.00k
        }
393
5.00k
        self
394
5.00k
    }
395
}
396
397
impl FormatterOptions {
398
    /// Character used as 'fill' whenever there is alignment.
399
    #[inline]
400
    #[must_use]
401
0
    pub const fn fill(&self) -> char {
402
0
        self.fill
403
0
    }
404
405
    /// Flag indicating what form of alignment was requested.
406
    #[inline]
407
    #[must_use]
408
0
    pub const fn align(&self) -> Option<Alignment> {
409
0
        self.align
410
0
    }
411
412
    /// Optionally specified integer width that the output should be.
413
    #[inline]
414
    #[must_use]
415
46.3k
    pub const fn width(&self) -> Option<usize> {
416
46.3k
        if (self.flags >> FlagBit::WidthIsInitialized as u8) & 1 == 1 {
417
            // Safety: `width` is initialized if the flag is set.
418
17.5k
            Some(unsafe { self.width.assume_init() })
419
        } else {
420
28.7k
            None
421
        }
422
46.3k
    }
<powerfmt::smart_display::FormatterOptions>::width
Line
Count
Source
415
46.3k
    pub const fn width(&self) -> Option<usize> {
416
46.3k
        if (self.flags >> FlagBit::WidthIsInitialized as u8) & 1 == 1 {
417
            // Safety: `width` is initialized if the flag is set.
418
17.5k
            Some(unsafe { self.width.assume_init() })
419
        } else {
420
28.7k
            None
421
        }
422
46.3k
    }
Unexecuted instantiation: <powerfmt::smart_display::FormatterOptions>::width
423
424
    /// Optionally specified precision for numeric types. Alternatively, the maximum width for
425
    /// string types.
426
    #[inline]
427
    #[must_use]
428
20.0k
    pub const fn precision(&self) -> Option<usize> {
429
20.0k
        if (self.flags >> FlagBit::PrecisionIsInitialized as u8) & 1 == 1 {
430
            // Safety: `precision` is initialized if the flag is set.
431
0
            Some(unsafe { self.precision.assume_init() })
432
        } else {
433
20.0k
            None
434
        }
435
20.0k
    }
<powerfmt::smart_display::FormatterOptions>::precision
Line
Count
Source
428
20.0k
    pub const fn precision(&self) -> Option<usize> {
429
20.0k
        if (self.flags >> FlagBit::PrecisionIsInitialized as u8) & 1 == 1 {
430
            // Safety: `precision` is initialized if the flag is set.
431
0
            Some(unsafe { self.precision.assume_init() })
432
        } else {
433
20.0k
            None
434
        }
435
20.0k
    }
Unexecuted instantiation: <powerfmt::smart_display::FormatterOptions>::precision
436
437
    /// Determines if the `+` flag was specified.
438
    #[inline]
439
    #[must_use]
440
20.0k
    pub const fn sign_plus(&self) -> bool {
441
20.0k
        (self.flags >> FlagBit::SignPlus as u8) & 1 == 1
442
20.0k
    }
443
444
    /// Determines if the `-` flag was specified.
445
    #[inline]
446
    #[must_use]
447
12.5k
    pub const fn sign_minus(&self) -> bool {
448
12.5k
        (self.flags >> FlagBit::SignMinus as u8) & 1 == 1
449
12.5k
    }
450
451
    /// Determines if the `#` flag was specified.
452
    #[inline]
453
    #[must_use]
454
0
    pub const fn alternate(&self) -> bool {
455
0
        (self.flags >> FlagBit::Alternate as u8) & 1 == 1
456
0
    }
457
458
    /// Determines if the `0` flag was specified.
459
    #[inline]
460
    #[must_use]
461
0
    pub const fn sign_aware_zero_pad(&self) -> bool {
462
0
        (self.flags >> FlagBit::SignAwareZeroPad as u8) & 1 == 1
463
0
    }
464
}
465
466
impl From<&Formatter<'_>> for FormatterOptions {
467
5.00k
    fn from(value: &Formatter<'_>) -> Self {
468
5.00k
        *Self::default()
469
5.00k
            .with_fill(value.fill())
470
5.00k
            .with_sign_plus(value.sign_plus())
471
5.00k
            .with_sign_minus(value.sign_minus())
472
5.00k
            .with_align(value.align())
473
5.00k
            .with_width(value.width())
474
5.00k
            .with_precision(value.precision())
475
5.00k
            .with_alternate(value.alternate())
476
5.00k
            .with_sign_aware_zero_pad(value.sign_aware_zero_pad())
477
5.00k
    }
478
}
479
480
impl From<&mut Formatter<'_>> for FormatterOptions {
481
    #[inline]
482
5.00k
    fn from(value: &mut Formatter<'_>) -> Self {
483
5.00k
        (&*value).into()
484
5.00k
    }
<powerfmt::smart_display::FormatterOptions as core::convert::From<&mut core::fmt::Formatter>>::from
Line
Count
Source
482
5.00k
    fn from(value: &mut Formatter<'_>) -> Self {
483
5.00k
        (&*value).into()
484
5.00k
    }
Unexecuted instantiation: <powerfmt::smart_display::FormatterOptions as core::convert::From<&mut core::fmt::Formatter>>::from
485
}
486
487
/// Information used to format a value. This is returned by [`SmartDisplay::metadata`].
488
///
489
/// This type is generic over any user-provided type. This allows the author to store any
490
/// information that is needed. For example, a type's implementation of [`SmartDisplay`] may need
491
/// to calculate something before knowing its width. This calculation can be performed, with the
492
/// result being stored in the custom metadata type.
493
///
494
/// Note that `Metadata` _always_ contains the width of the type. Authors do not need to store this
495
/// information in their custom metadata type.
496
///
497
/// Generally speaking, a type should be able to be formatted using only its metadata, fields, and
498
/// the formatter. Any other information should be stored in the metadata type.
499
pub struct Metadata<'a, T>
500
where
501
    T: SmartDisplay + ?Sized,
502
{
503
    unpadded_width: usize,
504
    metadata: T::Metadata,
505
    _value: PhantomData<&'a T>, // variance
506
}
507
508
// manual impls for bounds
509
impl<T> Debug for Metadata<'_, T>
510
where
511
    T: SmartDisplay,
512
    T::Metadata: Debug,
513
{
514
0
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
515
0
        f.debug_struct("Metadata")
516
0
            .field("unpadded_width", &self.unpadded_width)
517
0
            .field("metadata", &self.metadata)
518
0
            .finish()
519
0
    }
520
}
521
522
impl<T> Clone for Metadata<'_, T>
523
where
524
    T: SmartDisplay,
525
    T::Metadata: Clone,
526
{
527
0
    fn clone(&self) -> Self {
528
0
        Self {
529
0
            unpadded_width: self.unpadded_width,
530
0
            metadata: self.metadata.clone(),
531
0
            _value: self._value,
532
0
        }
533
0
    }
534
}
535
536
impl<T> Copy for Metadata<'_, T>
537
where
538
    T: SmartDisplay,
539
    T::Metadata: Copy,
540
{
541
}
542
543
impl<'a, T> Metadata<'a, T>
544
where
545
    T: SmartDisplay + ?Sized,
546
{
547
    /// Creates a new `Metadata` with the given width and metadata. While the width _should_ be
548
    /// exact, this is not a requirement for soundness.
549
51.3k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
51.3k
        Self {
551
51.3k
            unpadded_width,
552
51.3k
            metadata,
553
51.3k
            _value: PhantomData,
554
51.3k
        }
555
51.3k
    }
<powerfmt::smart_display::Metadata<time::utc_offset::UtcOffset>>::new
Line
Count
Source
549
2.50k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
2.50k
        Self {
551
2.50k
            unpadded_width,
552
2.50k
            metadata,
553
2.50k
            _value: PhantomData,
554
2.50k
        }
555
2.50k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<time::utc_date_time::UtcDateTime>>::new
<powerfmt::smart_display::Metadata<time::offset_date_time::OffsetDateTime>>::new
Line
Count
Source
549
1.25k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
1.25k
        Self {
551
1.25k
            unpadded_width,
552
1.25k
            metadata,
553
1.25k
            _value: PhantomData,
554
1.25k
        }
555
1.25k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<time::primitive_date_time::PrimitiveDateTime>>::new
<powerfmt::smart_display::Metadata<time::date::Date>>::new
Line
Count
Source
549
2.50k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
2.50k
        Self {
551
2.50k
            unpadded_width,
552
2.50k
            metadata,
553
2.50k
            _value: PhantomData,
554
2.50k
        }
555
2.50k
    }
<powerfmt::smart_display::Metadata<time::time::Time>>::new
Line
Count
Source
549
2.50k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
2.50k
        Self {
551
2.50k
            unpadded_width,
552
2.50k
            metadata,
553
2.50k
            _value: PhantomData,
554
2.50k
        }
555
2.50k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<time::month::Month>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<time::weekday::Weekday>>::new
<powerfmt::smart_display::Metadata<str>>::new
Line
Count
Source
549
20.0k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
20.0k
        Self {
551
20.0k
            unpadded_width,
552
20.0k
            metadata,
553
20.0k
            _value: PhantomData,
554
20.0k
        }
555
20.0k
    }
<powerfmt::smart_display::Metadata<i8>>::new
Line
Count
Source
549
7.51k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
7.51k
        Self {
551
7.51k
            unpadded_width,
552
7.51k
            metadata,
553
7.51k
            _value: PhantomData,
554
7.51k
        }
555
7.51k
    }
<powerfmt::smart_display::Metadata<char>>::new
Line
Count
Source
549
2.50k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
2.50k
        Self {
551
2.50k
            unpadded_width,
552
2.50k
            metadata,
553
2.50k
            _value: PhantomData,
554
2.50k
        }
555
2.50k
    }
<powerfmt::smart_display::Metadata<u8>>::new
Line
Count
Source
549
12.5k
    pub const fn new(unpadded_width: usize, _value: &T, metadata: T::Metadata) -> Self {
550
12.5k
        Self {
551
12.5k
            unpadded_width,
552
12.5k
            metadata,
553
12.5k
            _value: PhantomData,
554
12.5k
        }
555
12.5k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<isize>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<usize>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<i32>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<u32>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<i128>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<u128>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<i16>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<u16>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<i64>>::new
Unexecuted instantiation: <powerfmt::smart_display::Metadata<u64>>::new
556
557
    /// Reuse the metadata for another type. This is useful when implementing [`SmartDisplay`] for a
558
    /// type that wraps another type. Both type's metadata type must be the same.
559
73.8k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
73.8k
    where
561
73.8k
        'a: 'b,
562
73.8k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
73.8k
    {
564
73.8k
        Metadata {
565
73.8k
            unpadded_width: self.unpadded_width,
566
73.8k
            metadata: self.metadata,
567
73.8k
            _value: PhantomData,
568
73.8k
        }
569
73.8k
    }
<powerfmt::smart_display::Metadata<deranged::RangedI8<-25, 25>>>::reuse::<&deranged::RangedI8<-25, 25>>
Line
Count
Source
559
2.50k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
2.50k
    where
561
2.50k
        'a: 'b,
562
2.50k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
2.50k
    {
564
2.50k
        Metadata {
565
2.50k
            unpadded_width: self.unpadded_width,
566
2.50k
            metadata: self.metadata,
567
2.50k
            _value: PhantomData,
568
2.50k
        }
569
2.50k
    }
<powerfmt::smart_display::Metadata<deranged::RangedI8<-59, 59>>>::reuse::<&deranged::RangedI8<-59, 59>>
Line
Count
Source
559
5.00k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
5.00k
    where
561
5.00k
        'a: 'b,
562
5.00k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
5.00k
    {
564
5.00k
        Metadata {
565
5.00k
            unpadded_width: self.unpadded_width,
566
5.00k
            metadata: self.metadata,
567
5.00k
            _value: PhantomData,
568
5.00k
        }
569
5.00k
    }
<powerfmt::smart_display::Metadata<time::utc_offset::UtcOffset>>::reuse::<&time::utc_offset::UtcOffset>
Line
Count
Source
559
1.25k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
1.25k
    where
561
1.25k
        'a: 'b,
562
1.25k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
1.25k
    {
564
1.25k
        Metadata {
565
1.25k
            unpadded_width: self.unpadded_width,
566
1.25k
            metadata: self.metadata,
567
1.25k
            _value: PhantomData,
568
1.25k
        }
569
1.25k
    }
<powerfmt::smart_display::Metadata<time::date::Date>>::reuse::<&time::date::Date>
Line
Count
Source
559
1.25k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
1.25k
    where
561
1.25k
        'a: 'b,
562
1.25k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
1.25k
    {
564
1.25k
        Metadata {
565
1.25k
            unpadded_width: self.unpadded_width,
566
1.25k
            metadata: self.metadata,
567
1.25k
            _value: PhantomData,
568
1.25k
        }
569
1.25k
    }
<powerfmt::smart_display::Metadata<time::time::Time>>::reuse::<&time::time::Time>
Line
Count
Source
559
1.25k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
1.25k
    where
561
1.25k
        'a: 'b,
562
1.25k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
1.25k
    {
564
1.25k
        Metadata {
565
1.25k
            unpadded_width: self.unpadded_width,
566
1.25k
            metadata: self.metadata,
567
1.25k
            _value: PhantomData,
568
1.25k
        }
569
1.25k
    }
<powerfmt::smart_display::Metadata<&str>>::reuse::<&&str>
Line
Count
Source
559
20.0k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
20.0k
    where
561
20.0k
        'a: 'b,
562
20.0k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
20.0k
    {
564
20.0k
        Metadata {
565
20.0k
            unpadded_width: self.unpadded_width,
566
20.0k
            metadata: self.metadata,
567
20.0k
            _value: PhantomData,
568
20.0k
        }
569
20.0k
    }
<powerfmt::smart_display::Metadata<i8>>::reuse::<deranged::RangedI8<-25, 25>>
Line
Count
Source
559
2.50k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
2.50k
    where
561
2.50k
        'a: 'b,
562
2.50k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
2.50k
    {
564
2.50k
        Metadata {
565
2.50k
            unpadded_width: self.unpadded_width,
566
2.50k
            metadata: self.metadata,
567
2.50k
            _value: PhantomData,
568
2.50k
        }
569
2.50k
    }
<powerfmt::smart_display::Metadata<i8>>::reuse::<deranged::RangedI8<-59, 59>>
Line
Count
Source
559
5.00k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
5.00k
    where
561
5.00k
        'a: 'b,
562
5.00k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
5.00k
    {
564
5.00k
        Metadata {
565
5.00k
            unpadded_width: self.unpadded_width,
566
5.00k
            metadata: self.metadata,
567
5.00k
            _value: PhantomData,
568
5.00k
        }
569
5.00k
    }
<powerfmt::smart_display::Metadata<char>>::reuse::<&char>
Line
Count
Source
559
2.50k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
2.50k
    where
561
2.50k
        'a: 'b,
562
2.50k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
2.50k
    {
564
2.50k
        Metadata {
565
2.50k
            unpadded_width: self.unpadded_width,
566
2.50k
            metadata: self.metadata,
567
2.50k
            _value: PhantomData,
568
2.50k
        }
569
2.50k
    }
<powerfmt::smart_display::Metadata<str>>::reuse::<&str>
Line
Count
Source
559
20.0k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
20.0k
    where
561
20.0k
        'a: 'b,
562
20.0k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
20.0k
    {
564
20.0k
        Metadata {
565
20.0k
            unpadded_width: self.unpadded_width,
566
20.0k
            metadata: self.metadata,
567
20.0k
            _value: PhantomData,
568
20.0k
        }
569
20.0k
    }
<powerfmt::smart_display::Metadata<u8>>::reuse::<&u8>
Line
Count
Source
559
12.5k
    pub fn reuse<'b, U>(self) -> Metadata<'b, U>
560
12.5k
    where
561
12.5k
        'a: 'b,
562
12.5k
        U: SmartDisplay<Metadata = T::Metadata> + ?Sized,
563
12.5k
    {
564
12.5k
        Metadata {
565
12.5k
            unpadded_width: self.unpadded_width,
566
12.5k
            metadata: self.metadata,
567
12.5k
            _value: PhantomData,
568
12.5k
        }
569
12.5k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<_>>::reuse::<_>
570
571
    /// Obtain the width of the value before padding.
572
51.3k
    pub const fn unpadded_width(&self) -> usize {
573
51.3k
        self.unpadded_width
574
51.3k
    }
<powerfmt::smart_display::Metadata<time::utc_offset::UtcOffset>>::unpadded_width
Line
Count
Source
572
1.25k
    pub const fn unpadded_width(&self) -> usize {
573
1.25k
        self.unpadded_width
574
1.25k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<time::utc_date_time::UtcDateTime>>::unpadded_width
<powerfmt::smart_display::Metadata<time::offset_date_time::OffsetDateTime>>::unpadded_width
Line
Count
Source
572
1.25k
    pub const fn unpadded_width(&self) -> usize {
573
1.25k
        self.unpadded_width
574
1.25k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<time::primitive_date_time::PrimitiveDateTime>>::unpadded_width
<powerfmt::smart_display::Metadata<time::date::Date>>::unpadded_width
Line
Count
Source
572
1.25k
    pub const fn unpadded_width(&self) -> usize {
573
1.25k
        self.unpadded_width
574
1.25k
    }
<powerfmt::smart_display::Metadata<time::time::Time>>::unpadded_width
Line
Count
Source
572
1.25k
    pub const fn unpadded_width(&self) -> usize {
573
1.25k
        self.unpadded_width
574
1.25k
    }
<powerfmt::smart_display::Metadata<&deranged::RangedI8<-25, 25>>>::unpadded_width
Line
Count
Source
572
2.50k
    pub const fn unpadded_width(&self) -> usize {
573
2.50k
        self.unpadded_width
574
2.50k
    }
<powerfmt::smart_display::Metadata<&deranged::RangedI8<-59, 59>>>::unpadded_width
Line
Count
Source
572
5.00k
    pub const fn unpadded_width(&self) -> usize {
573
5.00k
        self.unpadded_width
574
5.00k
    }
<powerfmt::smart_display::Metadata<&time::utc_offset::UtcOffset>>::unpadded_width
Line
Count
Source
572
1.25k
    pub const fn unpadded_width(&self) -> usize {
573
1.25k
        self.unpadded_width
574
1.25k
    }
<powerfmt::smart_display::Metadata<&time::date::Date>>::unpadded_width
Line
Count
Source
572
1.25k
    pub const fn unpadded_width(&self) -> usize {
573
1.25k
        self.unpadded_width
574
1.25k
    }
<powerfmt::smart_display::Metadata<&time::time::Time>>::unpadded_width
Line
Count
Source
572
1.25k
    pub const fn unpadded_width(&self) -> usize {
573
1.25k
        self.unpadded_width
574
1.25k
    }
<powerfmt::smart_display::Metadata<&&str>>::unpadded_width
Line
Count
Source
572
20.0k
    pub const fn unpadded_width(&self) -> usize {
573
20.0k
        self.unpadded_width
574
20.0k
    }
<powerfmt::smart_display::Metadata<&char>>::unpadded_width
Line
Count
Source
572
2.50k
    pub const fn unpadded_width(&self) -> usize {
573
2.50k
        self.unpadded_width
574
2.50k
    }
<powerfmt::smart_display::Metadata<&u8>>::unpadded_width
Line
Count
Source
572
12.5k
    pub const fn unpadded_width(&self) -> usize {
573
12.5k
        self.unpadded_width
574
12.5k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<_>>::unpadded_width
575
576
    /// Obtain the width of the value after padding.
577
46.3k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
46.3k
        match f.width() {
579
17.5k
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
28.7k
            None => self.unpadded_width(),
581
        }
582
46.3k
    }
<powerfmt::smart_display::Metadata<&deranged::RangedI8<-25, 25>>>::padded_width
Line
Count
Source
577
2.50k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
2.50k
        match f.width() {
579
2.50k
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
0
            None => self.unpadded_width(),
581
        }
582
2.50k
    }
<powerfmt::smart_display::Metadata<&deranged::RangedI8<-59, 59>>>::padded_width
Line
Count
Source
577
5.00k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
5.00k
        match f.width() {
579
5.00k
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
0
            None => self.unpadded_width(),
581
        }
582
5.00k
    }
<powerfmt::smart_display::Metadata<&time::utc_offset::UtcOffset>>::padded_width
Line
Count
Source
577
1.25k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
1.25k
        match f.width() {
579
0
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
1.25k
            None => self.unpadded_width(),
581
        }
582
1.25k
    }
<powerfmt::smart_display::Metadata<&time::date::Date>>::padded_width
Line
Count
Source
577
1.25k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
1.25k
        match f.width() {
579
0
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
1.25k
            None => self.unpadded_width(),
581
        }
582
1.25k
    }
<powerfmt::smart_display::Metadata<&time::time::Time>>::padded_width
Line
Count
Source
577
1.25k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
1.25k
        match f.width() {
579
0
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
1.25k
            None => self.unpadded_width(),
581
        }
582
1.25k
    }
<powerfmt::smart_display::Metadata<&&str>>::padded_width
Line
Count
Source
577
20.0k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
20.0k
        match f.width() {
579
0
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
20.0k
            None => self.unpadded_width(),
581
        }
582
20.0k
    }
<powerfmt::smart_display::Metadata<&char>>::padded_width
Line
Count
Source
577
2.50k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
2.50k
        match f.width() {
579
0
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
2.50k
            None => self.unpadded_width(),
581
        }
582
2.50k
    }
<powerfmt::smart_display::Metadata<&u8>>::padded_width
Line
Count
Source
577
12.5k
    pub fn padded_width(&self, f: FormatterOptions) -> usize {
578
12.5k
        match f.width() {
579
10.0k
            Some(requested_width) => cmp::max(self.unpadded_width(), requested_width),
580
2.50k
            None => self.unpadded_width(),
581
        }
582
12.5k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<_>>::padded_width
583
}
584
585
impl Metadata<'_, Infallible> {
586
    /// Obtain the width of the value before padding, given the formatter options.
587
0
    pub fn unpadded_width_of<T>(value: T, f: FormatterOptions) -> usize
588
0
    where
589
0
        T: SmartDisplay,
590
0
    {
591
0
        value.metadata(f).unpadded_width
592
0
    }
593
594
    /// Obtain the width of the value after padding, given the formatter options.
595
46.3k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
46.3k
    where
597
46.3k
        T: SmartDisplay,
598
46.3k
    {
599
46.3k
        value.metadata(f).padded_width(f)
600
46.3k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&deranged::RangedI8<-25, 25>>
Line
Count
Source
595
2.50k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
2.50k
    where
597
2.50k
        T: SmartDisplay,
598
2.50k
    {
599
2.50k
        value.metadata(f).padded_width(f)
600
2.50k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&deranged::RangedI8<-59, 59>>
Line
Count
Source
595
5.00k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
5.00k
    where
597
5.00k
        T: SmartDisplay,
598
5.00k
    {
599
5.00k
        value.metadata(f).padded_width(f)
600
5.00k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&time::utc_offset::UtcOffset>
Line
Count
Source
595
1.25k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
1.25k
    where
597
1.25k
        T: SmartDisplay,
598
1.25k
    {
599
1.25k
        value.metadata(f).padded_width(f)
600
1.25k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&time::date::Date>
Line
Count
Source
595
1.25k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
1.25k
    where
597
1.25k
        T: SmartDisplay,
598
1.25k
    {
599
1.25k
        value.metadata(f).padded_width(f)
600
1.25k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&time::time::Time>
Line
Count
Source
595
1.25k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
1.25k
    where
597
1.25k
        T: SmartDisplay,
598
1.25k
    {
599
1.25k
        value.metadata(f).padded_width(f)
600
1.25k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&&str>
Line
Count
Source
595
20.0k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
20.0k
    where
597
20.0k
        T: SmartDisplay,
598
20.0k
    {
599
20.0k
        value.metadata(f).padded_width(f)
600
20.0k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&char>
Line
Count
Source
595
2.50k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
2.50k
    where
597
2.50k
        T: SmartDisplay,
598
2.50k
    {
599
2.50k
        value.metadata(f).padded_width(f)
600
2.50k
    }
<powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<&u8>
Line
Count
Source
595
12.5k
    pub fn padded_width_of<T>(value: T, f: FormatterOptions) -> usize
596
12.5k
    where
597
12.5k
        T: SmartDisplay,
598
12.5k
    {
599
12.5k
        value.metadata(f).padded_width(f)
600
12.5k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<core::convert::Infallible>>::padded_width_of::<_>
601
}
602
603
/// Permit using `Metadata` as a smart pointer to the user-provided metadata.
604
impl<T> Deref for Metadata<'_, T>
605
where
606
    T: SmartDisplay + ?Sized,
607
{
608
    type Target = T::Metadata;
609
610
3.75k
    fn deref(&self) -> &T::Metadata {
611
3.75k
        &self.metadata
612
3.75k
    }
<powerfmt::smart_display::Metadata<time::date::Date> as core::ops::deref::Deref>::deref
Line
Count
Source
610
1.25k
    fn deref(&self) -> &T::Metadata {
611
1.25k
        &self.metadata
612
1.25k
    }
<powerfmt::smart_display::Metadata<time::time::Time> as core::ops::deref::Deref>::deref
Line
Count
Source
610
2.50k
    fn deref(&self) -> &T::Metadata {
611
2.50k
        &self.metadata
612
2.50k
    }
Unexecuted instantiation: <powerfmt::smart_display::Metadata<_> as core::ops::deref::Deref>::deref
613
}
614
615
/// Format trait that allows authors to provide additional information.
616
///
617
/// This trait is similar to [`Display`], but allows the author to provide additional information
618
/// to the formatter. This information is provided in the form of a custom metadata type.
619
///
620
/// The only required piece of metadata is the width of the value. This is _before_ it is passed to
621
/// the formatter (i.e. it does not include any padding added by the formatter). Other information
622
/// can be stored in a custom metadata type as needed. This information may be made available to
623
/// downstream users, but it is not required.
624
///
625
/// **Note**: While both `fmt_with_metadata` and `fmt` have default implementations, it is strongly
626
/// recommended to implement only `fmt_with_metadata`. `fmt` should be implemented if and only if
627
/// the type does not require any of the calculated metadata. In that situation, `fmt_with_metadata`
628
/// should be omitted.
629
#[cfg_attr(__powerfmt_docs, rustc_must_implement_one_of(fmt, fmt_with_metadata))]
630
pub trait SmartDisplay: Display {
631
    /// User-provided metadata type.
632
    type Metadata;
633
634
    /// Compute any information needed to format the value. This must, at a minimum, determine the
635
    /// width of the value before any padding is added by the formatter.
636
    ///
637
    /// If the type uses other types that implement `SmartDisplay` verbatim, the inner types should
638
    /// have their metadata calculated and included in the returned value.
639
    ///
640
    /// # Lifetimes
641
    ///
642
    /// This method's return type contains a lifetime to `self`. This ensures that the metadata will
643
    /// neither outlive the value nor be invalidated by a mutation of the value (barring interior
644
    /// mutability).
645
    ///
646
    /// ```rust,compile_fail
647
    /// # use std::fmt;
648
    /// # use std::fmt::Write;
649
    /// # use powerfmt::buf::WriteBuffer;
650
    /// # use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};
651
    /// #[derive(Debug)]
652
    /// struct WrappedBuffer(WriteBuffer<128>);
653
    ///
654
    /// #[smart_display::delegate]
655
    /// impl SmartDisplay for WrappedBuffer {
656
    ///     type Metadata = ();
657
    ///
658
    ///     fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
659
    ///         Metadata::new(self.0.len(), self, ())
660
    ///     }
661
    ///
662
    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
663
    ///         f.pad(self.0.as_str())
664
    ///     }
665
    /// }
666
    ///
667
    /// let mut buf = WrappedBuffer(WriteBuffer::new());
668
    /// let metadata = buf.metadata(FormatterOptions::default());
669
    /// // We cannot mutate the buffer while it is borrowed and use its previous metadata on the
670
    /// // following line.
671
    /// write!(buf.0, "Hello, world!")?;
672
    /// assert_eq!(metadata.width(), 13);
673
    /// # Ok::<(), Box<dyn std::error::Error>>(())
674
    /// ```
675
    fn metadata(&self, f: FormatterOptions) -> Metadata<'_, Self>;
676
677
    /// Format the value using the given formatter and metadata. The formatted output should have
678
    /// the width indicated by the metadata. This is before any padding is added by the
679
    /// formatter.
680
    ///
681
    /// If the metadata is not needed, you should implement the `fmt` method instead.
682
0
    fn fmt_with_metadata(&self, f: &mut Formatter<'_>, _metadata: Metadata<'_, Self>) -> Result {
683
0
        SmartDisplay::fmt(self, f)
684
0
    }
685
686
    /// Format the value using the given formatter. This is the same as [`Display::fmt`].
687
    ///
688
    /// The default implementation of this method calls `fmt_with_metadata` with the result of
689
    /// `metadata`. Generally speaking, this method should not be implemented. You should implement
690
    /// the `fmt_with_metadata` method instead.
691
5.00k
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
692
5.00k
        let metadata = self.metadata(f.into());
693
5.00k
        self.fmt_with_metadata(f, metadata)
694
5.00k
    }
Unexecuted instantiation: <time::utc_date_time::UtcDateTime as powerfmt::smart_display::SmartDisplay>::fmt
Unexecuted instantiation: <time::primitive_date_time::PrimitiveDateTime as powerfmt::smart_display::SmartDisplay>::fmt
<time::utc_offset::UtcOffset as powerfmt::smart_display::SmartDisplay>::fmt
Line
Count
Source
691
1.25k
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
692
1.25k
        let metadata = self.metadata(f.into());
693
1.25k
        self.fmt_with_metadata(f, metadata)
694
1.25k
    }
<time::time::Time as powerfmt::smart_display::SmartDisplay>::fmt
Line
Count
Source
691
1.25k
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
692
1.25k
        let metadata = self.metadata(f.into());
693
1.25k
        self.fmt_with_metadata(f, metadata)
694
1.25k
    }
<time::date::Date as powerfmt::smart_display::SmartDisplay>::fmt
Line
Count
Source
691
1.25k
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
692
1.25k
        let metadata = self.metadata(f.into());
693
1.25k
        self.fmt_with_metadata(f, metadata)
694
1.25k
    }
<time::offset_date_time::OffsetDateTime as powerfmt::smart_display::SmartDisplay>::fmt
Line
Count
Source
691
1.25k
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
692
1.25k
        let metadata = self.metadata(f.into());
693
1.25k
        self.fmt_with_metadata(f, metadata)
694
1.25k
    }
Unexecuted instantiation: <_ as powerfmt::smart_display::SmartDisplay>::fmt
695
}