fmt_tools/
fmt_display.rs

1use core::fmt::{self, Debug, Display, Formatter};
2
3/// [`Debug`] or [`Display`] a value based on its [`Display`] implementation.
4pub struct FmtDisplay<T>
5where
6    T: ?Sized,
7{
8    value: T,
9}
10
11impl<T> FmtDisplay<T> {
12    const fn new(value: T) -> Self {
13        Self { value }
14    }
15}
16
17impl<T> Debug for FmtDisplay<T>
18where
19    T: Display + ?Sized,
20{
21    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
22        self.value.fmt(f)
23    }
24}
25
26impl<T> Display for FmtDisplay<T>
27where
28    T: Display + ?Sized,
29{
30    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
31        self.value.fmt(f)
32    }
33}
34
35/// Creates an object that [`Debug`] or [`Display`] a value based on its [`Display`] implementation.
36///
37/// Example:
38///
39/// ```rust
40/// use std::fmt::{self, Display, Formatter};
41///
42/// struct Foo;
43///
44/// impl Display for Foo {
45///     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
46///         f.write_str("foo")
47///     }
48/// }
49///
50/// let fmt = fmt_tools::fmt_display(Foo);
51///
52/// assert_eq!(format!("{fmt:?}"), "foo");
53/// assert_eq!(format!("{fmt}"), "foo");
54/// ```
55pub const fn fmt_display<T>(value: T) -> FmtDisplay<T>
56where
57    T: Display,
58{
59    FmtDisplay::new(value)
60}
61
62#[cfg(test)]
63mod tests {
64    use super::FmtDisplay;
65    use core::fmt::{self, Display, Formatter};
66
67    #[test]
68    fn test_fmt_display() {
69        struct Foo;
70
71        impl Display for Foo {
72            fn fmt(&self, f: &mut Formatter) -> fmt::Result {
73                f.write_str("foo")
74            }
75        }
76
77        let fmt = super::fmt_display(Foo);
78        let unsized_fmt: &FmtDisplay<dyn Display> = &fmt;
79
80        assert_eq!(std::format!("{fmt:?}"), "foo");
81        assert_eq!(std::format!("{fmt}"), "foo");
82        assert_eq!(std::format!("{unsized_fmt:?}"), "foo");
83        assert_eq!(std::format!("{unsized_fmt}"), "foo");
84    }
85}