hl2_lib/
highlight_scheme.rs

1use std::str::FromStr;
2
3use colored::{Color, Styles, Colorize};
4use regex::Regex;
5
6#[derive(Debug)]
7pub struct HighlightScheme {
8    /// regex for matching what data needs formatting
9    re: Regex,
10    /// the colour, if any, to format with.
11    color: Color,
12    /// the style, if any, to format with.
13    style: Styles,
14}
15
16impl HighlightScheme {
17    pub fn new(regex_expr: &str, color: &str, style: Styles) -> Result<Self, regex::Error> {
18        let re = regex::Regex::new(regex_expr)?;
19        return Ok(HighlightScheme {re, color: Color::from_str(color).expect("could not get color"), style });
20    }
21
22    pub fn builder(regex_expr: &str) -> Result<HighlightSchemeBuilder, regex::Error> {
23        let re = regex::Regex::new(regex_expr)?;
24        return Ok(HighlightSchemeBuilder { re, color: None, style: None });
25    }
26
27    /// This function formats the whole slice passed to it, it does not re-check the regex.
28    pub fn format_whole_slice(&self, string_to_format: &str) -> String {
29        let colored_string = string_to_format.to_string().color(self.color);
30        return match self.style {
31            Styles::Clear => colored_string,
32            Styles::Bold => colored_string.bold(),
33            Styles::Dimmed => colored_string.dimmed(),
34            Styles::Underline => colored_string.underline(),
35            Styles::Reversed => colored_string.reversed(),
36            Styles::Italic => colored_string.italic(),
37            Styles::Blink => colored_string.blink(),
38            Styles::Hidden => colored_string.hidden(),
39            Styles::Strikethrough => colored_string.strikethrough(),
40        }.to_string();
41    }
42
43    /// this function does the regex search and formats the correct parts of the
44    /// line and returns them as a new string.
45    ///
46    /// N.B. this function might behave oddly if passed slices of multiple lines.
47    pub fn format_line(&self, mut line_to_format: &str) -> String {
48        debug_assert!(!line_to_format.contains("\n"), "format_line should not be passed slices containing \\n");
49        let mut new_line = String::new();
50        while let Some(m) = self.re.find(&line_to_format) {
51            // doing this as a push_str breaks the colour formatter,
52            // so do it like this.
53            new_line = format!("{}{}{}",
54                new_line,
55                &line_to_format[..m.start()],
56                &line_to_format[m.range()].color(self.color.clone()));
57            line_to_format = &line_to_format[m.end()..];
58        }
59        return format!("{}{}", new_line, &line_to_format);
60    }
61}
62
63pub struct HighlightSchemeBuilder {
64    re: Regex,
65    color: Option<Color>,
66    style: Option<Styles>
67}
68
69impl HighlightSchemeBuilder {
70    pub fn build(self) -> HighlightScheme {
71        return HighlightScheme { re: self.re, color: self.color.unwrap_or(Color::White), style: self.style.unwrap_or(Styles::Clear) };
72    }
73
74    pub fn with_style(mut self, s: Styles) -> Self {
75        self.style = Some(s);
76        return self;
77    }
78
79    pub fn with_color(mut self, s: Color) -> Self {
80        self.color = Some(s);
81        return self;
82    }
83}