Skip to main content

zql_cli/util/
painter.rs

1use crate::error::MyResult;
2use std::io::Write;
3
4#[derive(Clone, Copy)]
5pub enum Style {
6    Column,
7    Type,
8    Number,
9    Text,
10    Reset,
11}
12
13#[derive(Clone, Copy)]
14pub enum Painter {
15    None,
16    Escape,
17    #[cfg(test)]
18    Test,
19}
20
21impl Painter {
22    pub fn print_line<W: Write>(
23        self,
24        writer: &mut W,
25        style: Style,
26        value: &str,
27    ) -> MyResult<()> {
28        self.set_style(writer, style)?;
29        write!(writer, "{}", value)?;
30        self.set_style(writer, Style::Reset)?;
31        writeln!(writer)?;
32        Ok(())
33    }
34
35    pub fn print_value<W: Write>(
36        self,
37        writer: &mut W,
38        style: Style,
39        value: &str,
40        left: usize,
41        right: usize,
42    ) -> MyResult<()> {
43        for _ in 0..left {
44            write!(writer, " ")?;
45        }
46        self.set_style(writer, style)?;
47        write!(writer, "{}", value)?;
48        self.set_style(writer, Style::Reset)?;
49        for _ in 0..right {
50            write!(writer, " ")?;
51        }
52        Ok(())
53    }
54
55    pub fn print_hyphens<W: Write>(
56        self,
57        writer: &mut W,
58        style: Style,
59        width: usize,
60        inner: bool,
61    ) -> MyResult<()> {
62        self.set_style(writer, style)?;
63        for _ in 0..=width {
64            write!(writer, "-")?;
65        }
66        self.set_style(writer, Style::Reset)?;
67        if inner {
68            write!(writer, " ")?;
69        }
70        Ok(())
71    }
72
73    pub fn wrap_style(&self, text: &str, style: Style) -> String {
74        if !text.is_empty() {
75            match self {
76                Self::None => String::from(text),
77                Self::Escape => format!("{}{}{}", get_escape(style), text, get_escape(Style::Reset)),
78                #[cfg(test)]
79                Self::Test => format!("{}{}{}", get_test(style), text, get_test(Style::Reset)),
80            }
81        } else {
82            String::new()
83        }
84    }
85
86    fn set_style<W: Write>(&self, writer: &mut W, style: Style) -> MyResult<()> {
87        match self {
88            Self::None => (),
89            Self::Escape => write!(writer, "{}", get_escape(style))?,
90            #[cfg(test)]
91            Self::Test => write!(writer, "{}", get_test(style))?,
92        }
93        Ok(())
94    }
95}
96
97fn get_escape(style: Style) -> &'static str {
98    match style {
99        Style::Column => "\x1b[33m", // (yellow)
100        Style::Type => "\x1b[31m", // (red)
101        Style::Number => "\x1b[32m", // (green)
102        Style::Text => "\x1b[36m", // (cyan)
103        Style::Reset => "\x1b[0m",
104    }
105}
106
107#[cfg(test)]
108fn get_test(style: Style) -> &'static str {
109    match style {
110        Style::Column => "[COL]",
111        Style::Type => "[TYP]",
112        Style::Number => "[NUM]",
113        Style::Text => "[VAL]",
114        Style::Reset => "[RES]",
115    }
116}