Skip to main content

facet_pretty/
display.rs

1//! Display trait implementations for pretty-printing Facet types
2
3use core::fmt::{self, Display, Formatter};
4
5use crate::printer::PrettyPrinter;
6use facet_core::Facet;
7
8/// Display wrapper for any type that implements Facet.
9///
10/// The lifetime `'b` is the borrow lifetime (how long we hold the reference),
11/// while `'a` is the Facet lifetime (for the type's shape/vtable).
12pub struct PrettyDisplay<'a, 'b, T: Facet<'a> + ?Sized> {
13    pub(crate) value: &'b T,
14    pub(crate) printer: PrettyPrinter,
15    pub(crate) _marker: core::marker::PhantomData<&'a ()>,
16}
17
18impl<'a, 'b, T: Facet<'a>> Display for PrettyDisplay<'a, 'b, T> {
19    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
20        self.printer.format_to(self.value, f)
21    }
22}
23
24/// Extension trait for Facet types to easily pretty-print them
25pub trait FacetPretty<'a>: Facet<'a> {
26    /// Get a displayable wrapper that pretty-prints this value
27    fn pretty(&self) -> PrettyDisplay<'a, '_, Self>;
28
29    /// Get a displayable wrapper with custom printer settings
30    fn pretty_with(&self, printer: PrettyPrinter) -> PrettyDisplay<'a, '_, Self>;
31}
32
33impl<'a, T: Facet<'a>> FacetPretty<'a> for T {
34    fn pretty(&self) -> PrettyDisplay<'a, '_, Self> {
35        PrettyDisplay {
36            value: self,
37            printer: PrettyPrinter::new(),
38            _marker: core::marker::PhantomData,
39        }
40    }
41
42    fn pretty_with(&self, printer: PrettyPrinter) -> PrettyDisplay<'a, '_, Self> {
43        PrettyDisplay {
44            value: self,
45            printer,
46            _marker: core::marker::PhantomData,
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use core::fmt::Write;
55    use facet::Facet;
56
57    // Use the derive macro from facet
58    #[derive(Facet)]
59    struct TestStruct {
60        field: u32,
61    }
62
63    #[test]
64    fn test_pretty_display() {
65        let test = TestStruct { field: 42 };
66        let display = test.pretty();
67
68        let mut output = String::new();
69        write!(output, "{display}").unwrap();
70
71        // Just check that it contains the field name and doesn't panic
72        assert!(output.contains("field"));
73    }
74
75    #[test]
76    fn test_pretty_with_custom_printer() {
77        let test = TestStruct { field: 42 };
78        let printer = PrettyPrinter::new().with_colors(false.into());
79        let display = test.pretty_with(printer);
80
81        let mut output = String::new();
82        write!(output, "{display}").unwrap();
83
84        // Just check that it contains the field name and doesn't panic
85        assert!(output.contains("field"));
86    }
87}