iota_aws_orchestrator/
display.rs1use std::{fmt::Display, io::stdout};
6
7use crossterm::{
8 cursor::{RestorePosition, SavePosition},
9 style::{Print, PrintStyledContent, Stylize},
10 terminal::{Clear, ClearType},
11};
12use prettytable::format::{self};
13
14pub fn header<S: Display>(message: S) {
15 crossterm::execute!(
16 stdout(),
17 PrintStyledContent(format!("\n{message}\n").green().bold()),
18 )
19 .unwrap();
20}
21
22pub fn error<S: Display>(message: S) {
23 crossterm::execute!(
24 stdout(),
25 PrintStyledContent(format!("\n{message}\n").red().bold()),
26 )
27 .unwrap();
28}
29
30pub fn warn<S: Display>(message: S) {
31 crossterm::execute!(
32 stdout(),
33 PrintStyledContent(format!("\n{message}\n").bold()),
34 )
35 .unwrap();
36}
37
38pub fn config<N: Display, V: Display>(name: N, value: V) {
39 crossterm::execute!(
40 stdout(),
41 PrintStyledContent(format!("{name}: ").bold()),
42 Print(format!("{value}\n"))
43 )
44 .unwrap();
45}
46
47pub fn action<S: Display>(message: S) {
48 crossterm::execute!(stdout(), Print(format!("{message} ... ")), SavePosition).unwrap();
49}
50
51pub fn status<S: Display>(status: S) {
52 crossterm::execute!(
53 stdout(),
54 RestorePosition,
55 SavePosition,
56 Clear(ClearType::UntilNewLine),
57 Print(format!("[{status}]"))
58 )
59 .unwrap();
60}
61
62pub fn done() {
63 crossterm::execute!(
64 stdout(),
65 RestorePosition,
66 Clear(ClearType::UntilNewLine),
67 Print(format!("[{}]\n", "Ok".green()))
68 )
69 .unwrap();
70}
71
72pub fn newline() {
73 crossterm::execute!(stdout(), Print("\n")).unwrap();
74}
75
76pub fn default_table_format() -> format::TableFormat {
78 format::FormatBuilder::new()
79 .separators(
80 &[
81 format::LinePosition::Top,
82 format::LinePosition::Bottom,
83 format::LinePosition::Title,
84 ],
85 format::LineSeparator::new('-', '-', '-', '-'),
86 )
87 .padding(1, 1)
88 .build()
89}
90
91#[cfg(test)]
92mod test {
93 use std::time::Duration;
94
95 use tokio::time::sleep;
96
97 use super::{action, config, done, error, header, newline, warn};
98 use crate::display::status;
99
100 #[tokio::test]
101 #[ignore = "only used to manually check if prints work correctly"]
102 async fn display() {
103 header("This is a header");
104 config("This is a config", 2);
105 action("Running a long function");
106 for i in 0..5 {
107 sleep(Duration::from_secs(1)).await;
108 if i == 2 {
109 warn("This is a warning!");
110 }
111 status(format!("{}/5", i + 1));
112 }
113 done();
114 error("This is an error!");
115 warn("This is a warning!");
116 newline();
117 }
118}