termprofile/convert/
adapt.rs

1use anstyle::{Ansi256Color, AnsiColor, Color, RgbColor, Style};
2
3/// Represents a color that can be converted to each type of color level.
4pub trait AdaptableColor {
5    /// Returns the color as an [`RgbColor`] if a compatible representation exists.
6    fn as_rgb(&self) -> Option<RgbColor>;
7    /// Returns the color as an [`Ansi256Color`] if a compatible representation exists.
8    fn as_ansi_256(&self) -> Option<Ansi256Color>;
9    /// Returns the color as an [`AnsiColor`] if a compatible representation exists.
10    fn as_ansi_16(&self) -> Option<AnsiColor>;
11    /// Creates a new instance from an [`Ansi256Color`].
12    fn from_ansi_256(color: Ansi256Color) -> Self;
13    /// Creates a new instance from an [`AnsiColor`].
14    fn from_ansi_16(color: AnsiColor) -> Self;
15}
16
17/// Represents a style that can get and set its color properties.
18pub trait AdaptableStyle: Default {
19    /// The color type used for the style properties.
20    type Color: AdaptableColor;
21
22    /// Returns the foreground color, if set.
23    fn get_fg_color(&self) -> Option<Self::Color>;
24    /// Returns the background color, if set.
25    fn get_bg_color(&self) -> Option<Self::Color>;
26    /// Returns the underline color, if set.
27    fn get_underline_color(&self) -> Option<Self::Color>;
28    /// Sets the foreground color.
29    fn fg_color(self, color: Option<Self::Color>) -> Self;
30    /// Sets the background color.
31    fn bg_color(self, color: Option<Self::Color>) -> Self;
32    /// Sets the underline color.
33    fn underline_color(self, color: Option<Self::Color>) -> Self;
34}
35
36impl AdaptableColor for Color {
37    fn as_rgb(&self) -> Option<RgbColor> {
38        if let Self::Rgb(color) = self {
39            Some(*color)
40        } else {
41            None
42        }
43    }
44
45    fn as_ansi_256(&self) -> Option<Ansi256Color> {
46        if let Self::Ansi256(color) = self {
47            Some(*color)
48        } else {
49            None
50        }
51    }
52
53    fn as_ansi_16(&self) -> Option<AnsiColor> {
54        if let Self::Ansi(color) = self {
55            Some(*color)
56        } else {
57            None
58        }
59    }
60
61    fn from_ansi_256(color: Ansi256Color) -> Self {
62        color.into()
63    }
64
65    fn from_ansi_16(color: AnsiColor) -> Self {
66        color.into()
67    }
68}
69
70impl AdaptableStyle for Style {
71    type Color = Color;
72
73    fn get_fg_color(&self) -> Option<Self::Color> {
74        (*self).get_fg_color()
75    }
76
77    fn get_bg_color(&self) -> Option<Self::Color> {
78        (*self).get_bg_color()
79    }
80
81    fn get_underline_color(&self) -> Option<Self::Color> {
82        (*self).get_underline_color()
83    }
84
85    fn fg_color(self, color: Option<Self::Color>) -> Self {
86        self.fg_color(color)
87    }
88
89    fn bg_color(self, color: Option<Self::Color>) -> Self {
90        self.bg_color(color)
91    }
92
93    fn underline_color(self, color: Option<Self::Color>) -> Self {
94        self.underline_color(color)
95    }
96}