Skip to main content

custom_display/
default.rs

1// SPDX-FileCopyrightText: 2026 Marissa (cuddle puddle) <dev@princess.lgbt>
2//
3// SPDX-License-Identifier: MPL-2.0
4
5use std::fmt::{self, Display, Formatter};
6use std::marker::PhantomData;
7
8use super::{CustomDisplay, OwnedDisplayable, PrecisionBehavior};
9
10/**
11 * Returns a [`CustomDisplay`] that provides handling of [precision], [width],
12 * [fill and alignment] in the way specified by [`std::fmt`] for non-numeric
13 * types.
14 *
15 * For some type that implements [`Display`], returns a [`CustomDisplay`] that,
16 * when used by a [`Displayable`], truncates the formatted value based on
17 * [precision], pads it based on [width], [fill and alignment], and has a
18 * default [`Alignment`] of [`Left`]. This allows one to get the behavior
19 * specified by [`std::fmt`] for non-numeric types without having to implement
20 * the handling for [precision], [width], [fill and alignment] for their type.
21 * The returned [`CustomDisplay`] assumes all characters in formatted values
22 * have a monospace width of `1`.
23 *
24 * See also [`display_non_numeric()`].
25 *
26 * [precision]: std::fmt#precision
27 * [width]: std::fmt#width
28 * [fill and alignment]: std::fmt#fillalignment
29 * [`Displayable`]: crate::Displayable
30 * [`Alignment`]: std::fmt::Alignment
31 * [`Left`]: std::fmt::Alignment::Left
32 */
33#[inline]
34pub fn default_non_numeric<T>() -> DefaultNonNumeric<T>
35where
36    T: Display + ?Sized,
37{
38    DefaultNonNumeric(PhantomData)
39}
40
41/**
42 * Returns a wrapper around the given value that handles [precision], [width],
43 * [fill and alignment] in the way specified by [`std::fmt`] for non-numeric
44 * types.
45 *
46 * For some type that implements [`Display`], returns a wrapper that truncates
47 * the formatted value based on [precision], pads it based on [width],
48 * [fill and alignment], and has a default [`Alignment`] of [`Left`]. This
49 * allows one to get the behavior specified by [`std::fmt`] for non-numeric
50 * types without having to implement the handling for [precision], [width],
51 * [fill and alignment] for their type. This method assumes all characters in
52 * the formatted value have a monospace width of `1`.
53 *
54 * See also [`default_non_numeric()`].
55 *
56 * [precision]: std::fmt#precision
57 * [width]: std::fmt#width
58 * [fill and alignment]: std::fmt#fillalignment
59 * [`Alignment`]: std::fmt::Alignment
60 * [`Left`]: std::fmt::Alignment::Left
61 */
62#[inline]
63pub fn display_non_numeric<T>(value: &T) -> OwnedDisplayable<'_, DefaultNonNumeric<T>>
64where
65    T: Display + ?Sized,
66{
67    default_non_numeric().into_display(value)
68}
69
70/** See [`default_non_numeric()`]. */
71#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
72pub struct DefaultNonNumeric<T>(PhantomData<fn(T)>)
73where
74    T: Display + ?Sized;
75
76impl<T> CustomDisplay for DefaultNonNumeric<T>
77where
78    T: Display + ?Sized,
79{
80    type Value = T;
81    #[inline]
82    fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
83        value.fmt(f)
84    }
85    #[inline]
86    fn precision_behavior(&self) -> crate::PrecisionBehavior {
87        PrecisionBehavior::AutoTruncate
88    }
89    #[inline]
90    fn width_in_chars(&self, _value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
91        None
92    }
93}
94
95impl<T> Display for DefaultNonNumeric<T>
96where
97    T: Display + ?Sized,
98{
99    #[inline]
100    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
101        f.pad("DefaultAutoTruncate")
102    }
103}