unwind_context/
colored.rs

1use core::fmt::{Debug, Formatter, Result as FmtResult};
2
3use crate::AnsiColorScheme;
4
5/// An utility alternative [`core::fmt::Debug`] trait which can used for colored
6/// context formatting.
7///
8/// This trait is not intended to be used directly. It is used for coloring
9/// functions and arguments data returned by macros like
10/// [`build_unwind_context_data`] or [`unwind_context`] instead.
11///
12/// # Examples
13///
14/// ```rust
15/// use unwind_context::{are_colors_enabled, unwind_context, DebugAnsiColored};
16///
17/// fn fmt_example(writer: core::fmt::Write, value: impl Debug + DebugAnsiColored) {
18///     if are_colors_enabled() {
19///         let _ = writeln!(
20///             "{:?}",
21///             AnsiColored::new(value, &unwind_context::DEFAULT_DEFAULT_COLOR_SCHEME)
22///         );
23///     } else {
24///         let _ = writeln!("{value:?}");
25///     }
26/// }
27/// ```
28///
29/// [`build_unwind_context_data`]: crate::build_unwind_context_data
30/// [`unwind_context`]: crate::unwind_context
31pub trait DebugAnsiColored {
32    /// Formats the value using with colorization and a given
33    /// [`AnsiColorScheme`].
34    ///
35    /// # Errors
36    ///
37    /// This function will return an error if the value formatting fails.
38    fn fmt_colored(
39        &self,
40        f: &mut Formatter<'_>,
41        color_scheme: &'static AnsiColorScheme,
42    ) -> FmtResult;
43}
44
45/// An utility wrapper type is used to forward value [`core::fmt::Debug`]
46/// implementation to [`DebugAnsiColored`] implementation with a given
47/// [`AnsiColorScheme`].
48///
49/// This type is not intended to be used directly. Consider using macros like
50/// [`unwind_context`], [`unwind_context_with_io`] or
51/// [`unwind_context_with_fmt`] instead.
52///
53/// [`unwind_context`]: crate::unwind_context
54/// [`unwind_context_with_io`]: crate::unwind_context_with_io
55/// [`unwind_context_with_fmt`]: crate::unwind_context_with_fmt
56#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
57pub struct AnsiColored<T> {
58    /// The wrapped value to be formatted with [`DebugAnsiColored`].
59    pub value: T,
60    /// Selected color scheme.
61    pub color_scheme: &'static AnsiColorScheme,
62}
63
64impl<T> AnsiColored<T> {
65    /// Wraps a given `T` so its [`core::fmt::Debug`] implementation will
66    /// forward to `DebugAnsiColored` with a given color scheme.
67    ///
68    /// # Examples
69    ///
70    /// ```rust
71    /// let arg = unwind_context::AnsiColored::new(
72    ///     unwind_context::UnwindContextArg::new(Some("foo"), 123),
73    ///     &unwind_context::DEFAULT_DEFAULT_COLOR_SCHEME,
74    /// );
75    /// ```
76    ///
77    /// [`build_unwind_context_data`]: crate::build_unwind_context_data
78    /// [`unwind_context`]: crate::unwind_context
79    #[inline]
80    pub fn new(value: T, color_scheme: &'static AnsiColorScheme) -> Self {
81        Self {
82            value,
83            color_scheme,
84        }
85    }
86}
87
88impl<T> Debug for AnsiColored<T>
89where
90    T: DebugAnsiColored,
91{
92    #[inline]
93    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
94        DebugAnsiColored::fmt_colored(&self.value, f, self.color_scheme)
95    }
96}
97
98impl<T> DebugAnsiColored for &T
99where
100    T: DebugAnsiColored,
101{
102    #[inline]
103    fn fmt_colored(
104        &self,
105        f: &mut Formatter<'_>,
106        color_scheme: &'static AnsiColorScheme,
107    ) -> FmtResult {
108        DebugAnsiColored::fmt_colored(&**self, f, color_scheme)
109    }
110}