tembo/
tui.rs

1use colorful::{Color, Colorful, RGB as ColorfulRgb};
2use std::fmt;
3use tiny_gradient::{GradientDisplay, GradientStr, RGB};
4
5pub enum TemboCliLog<'a> {
6    Gradient(GradientDisplay<'a, [RGB; 3]>),
7    GradientLarge(GradientDisplay<'a, [RGB; 4]>),
8    Default(String),
9}
10
11impl fmt::Display for TemboCliLog<'_> {
12    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13        match self {
14            TemboCliLog::Gradient(gradient) => write!(f, "{}", gradient),
15            TemboCliLog::Default(message) => write!(f, "{}", message),
16            TemboCliLog::GradientLarge(gradient) => write!(f, "{}", gradient),
17        }
18    }
19}
20
21/// Utility for completely clearing the console when called
22pub fn clean_console() {
23    print!("{esc}c", esc = 27 as char);
24}
25
26#[allow(dead_code)]
27/// Prints a colored log to the console (defaults to `use tui::colors::salmon`)
28pub fn print_color(log: &str, color: Option<ColorfulRgb>) {
29    let color = color.unwrap_or(colors::sql_u());
30    println!("{}", log.color(color));
31}
32#[allow(dead_code)]
33pub fn print_gradient(log: &str) {
34    let gradient = GradientStr::gradient(
35        log,
36        [
37            RGB::new(255, 198, 217),
38            RGB::new(124, 207, 225),
39            RGB::new(137, 203, 166),
40            RGB::new(165, 213, 113),
41        ],
42    );
43    println!("{}", gradient);
44}
45
46#[allow(dead_code)]
47pub fn label(log: &str) {
48    println!("{} {}", "➜".bold(), colors::gradient_rainbow(log));
49}
50
51pub fn label_with_value(log: &str, value: &str) {
52    println!(
53        "{} {} {}",
54        "➜".bold(),
55        colors::gradient_rainbow(log),
56        value.color(Color::White).bold()
57    );
58}
59
60pub fn error(log: &str) {
61    println!(
62        "{} {}",
63        "✗".color(colors::bad()).bold(),
64        log.color(colors::bad())
65    );
66}
67
68#[allow(dead_code)]
69pub fn warning(log: &str) {
70    println!(
71        "{} {}",
72        "⚠".color(colors::schema_y()).bold(),
73        log.color(colors::schema_y())
74    );
75}
76
77pub fn info(log: &str) {
78    println!(
79        "{} {}",
80        "i".color(colors::schema_y()).bold(),
81        log.color(colors::schema_y())
82    );
83}
84
85pub fn confirmation(log: &str) {
86    println!(
87        "{} {}",
88        "✓".color(colors::indicator_good()).bold(),
89        colors::gradient_rainbow(log)
90    );
91}
92
93pub fn white_confirmation(log: &str) {
94    println!(
95        "{} {}",
96        "✓".color(colors::indicator_good()).bold(),
97        log.color(Color::White).bold()
98    );
99}
100
101#[allow(dead_code)]
102/// Tembo branded gradient chevrons for printing singular output
103pub fn chevrons<'a>() -> GradientDisplay<'a, [RGB; 4]> {
104    GradientStr::gradient(
105        &">>>>",
106        [
107            RGB::new(255, 198, 217),
108            RGB::new(124, 207, 225),
109            RGB::new(137, 203, 166),
110            RGB::new(165, 213, 113),
111        ],
112    )
113}
114
115pub fn logo<'a>() -> TemboCliLog<'a> {
116    colors::gradient_rainbow(">>> T E M B O")
117}
118
119pub fn instance_started(server_url: &str, stack: &str) {
120    let bar = "┃".color(colors::sql_u()).bold();
121    println!(
122        "\n{bar} {} instance {}: \n\n ➜ {}\n ➜ {}",
123        logo(),
124        "started".bg_rgb(255, 125, 127).color(Color::White).bold(),
125        format_args!(
126            "{} {}",
127            "Connection String:".color(Color::White).bold(),
128            server_url.bold()
129        ),
130        stack.color(colors::grey()).bold()
131    );
132    println!()
133}
134
135/// Helper function for printing indentations to the console
136pub fn indent(amount: u32) -> String {
137    let mut new_amount = String::new();
138
139    for _ in 0..amount {
140        new_amount.push('\n');
141    }
142    new_amount
143}
144
145pub mod colors {
146    use super::TemboCliLog;
147    use colorful::RGB as ColorfulRgb;
148    use spinoff::Color as SpinnerColor;
149    use tiny_gradient::{GradientStr, RGB};
150
151    pub fn sql_u() -> ColorfulRgb {
152        ColorfulRgb::new(255, 125, 127)
153    }
154
155    #[allow(dead_code)]
156    pub fn warning_light() -> ColorfulRgb {
157        ColorfulRgb::new(255, 244, 228)
158    }
159
160    pub fn schema_y() -> ColorfulRgb {
161        ColorfulRgb::new(233, 252, 135)
162    }
163
164    #[allow(dead_code)]
165    #[allow(clippy::needless_lifetimes)]
166    pub fn gradient_p<'a>(log: &'a str) -> TemboCliLog<'a> {
167        let term_program = std::env::var("TERM_PROGRAM").unwrap_or_default();
168        // aTerminal only supports 8 bit colors so gradients won't work
169        if term_program == "Apple_Terminal" {
170            return TemboCliLog::Default(log.to_string());
171        }
172        TemboCliLog::GradientLarge(GradientStr::gradient(
173            log,
174            [
175                RGB::new(255, 198, 217),
176                RGB::new(124, 207, 225),
177                RGB::new(137, 203, 166),
178                RGB::new(165, 213, 113),
179            ],
180        ))
181    }
182
183    pub fn gradient_rainbow(log: &str) -> TemboCliLog {
184        let term_program = std::env::var("TERM_PROGRAM").unwrap_or_default();
185        // aTerminal only supports 8 bit colors so gradients won't work
186        if term_program == "Apple_Terminal" {
187            return TemboCliLog::Default(log.to_string());
188        }
189        TemboCliLog::Gradient(GradientStr::gradient(
190            log,
191            [
192                RGB::new(247, 117, 119),
193                RGB::new(219, 57, 203),
194                RGB::new(202, 111, 229),
195            ],
196        ))
197    }
198
199    pub fn indicator_good() -> ColorfulRgb {
200        ColorfulRgb::new(132, 234, 189)
201    }
202
203    pub fn grey() -> ColorfulRgb {
204        ColorfulRgb::new(158, 162, 166)
205    }
206
207    pub fn bad() -> ColorfulRgb {
208        ColorfulRgb::new(250, 70, 102)
209    }
210
211    pub const SPINNER_COLOR: SpinnerColor = SpinnerColor::TrueColor {
212        r: 255,
213        g: 125,
214        b: 127,
215    };
216}