iota_aws_orchestrator/
display.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use 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
76/// Default style for tables printed to stdout.
77pub 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}