fmt_tools/
fmt_debug.rs

1use core::fmt::{self, Debug, Display, Formatter};
2
3/// [`Debug`] or [`Display`] a value based on its [`Debug`] implementation.
4pub struct FmtDebug<T>
5where
6    T: ?Sized,
7{
8    value: T,
9}
10
11impl<T> FmtDebug<T> {
12    const fn new(value: T) -> Self {
13        Self { value }
14    }
15}
16
17impl<T> Debug for FmtDebug<T>
18where
19    T: Debug + ?Sized,
20{
21    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
22        self.value.fmt(f)
23    }
24}
25
26impl<T> Display for FmtDebug<T>
27where
28    T: Debug + ?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 [`Debug`] implementation.
36///
37/// Example:
38///
39/// ```rust
40/// #[derive(Debug)]
41/// struct Foo;
42///
43/// let fmt = fmt_tools::fmt_debug(Foo);
44///
45/// assert_eq!(format!("{fmt:?}"), "Foo");
46/// assert_eq!(format!("{fmt}"), "Foo");
47/// ```
48pub const fn fmt_debug<T>(value: T) -> FmtDebug<T>
49where
50    T: Debug,
51{
52    FmtDebug::new(value)
53}
54
55#[cfg(test)]
56mod tests {
57    use super::FmtDebug;
58    use core::fmt::Debug;
59
60    #[test]
61    fn test_fmt_debug() {
62        #[derive(Debug)]
63        struct Foo;
64
65        let fmt = super::fmt_debug(Foo);
66        let unsized_fmt: &FmtDebug<dyn Debug> = &fmt;
67
68        assert_eq!(std::format!("{fmt:?}"), "Foo");
69        assert_eq!(std::format!("{fmt}"), "Foo");
70        assert_eq!(std::format!("{unsized_fmt:?}"), "Foo");
71        assert_eq!(std::format!("{unsized_fmt}"), "Foo");
72    }
73}