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}