duvet_core/
progress.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use console::style;
5use core::fmt;
6use once_cell::sync::Lazy;
7use std::time::Instant;
8
9static INTERNAL_CI: Lazy<bool> = Lazy::new(|| std::env::var("DUVET_INTERNAL_CI").is_ok());
10
11#[macro_export]
12macro_rules! progress {
13    ($progress:ident, $fmt:literal $($tt:tt)*) => {
14        $progress.finish(format_args!($fmt $($tt)*));
15    };
16    ($fmt:literal $($tt:tt)*) => {
17        $crate::progress::Progress::new(format_args!($fmt $($tt)*))
18    };
19}
20
21pub struct Progress {
22    start_time: Instant,
23}
24
25impl Progress {
26    pub fn new<T: fmt::Display>(v: T) -> Self {
27        let start_time = Instant::now();
28        let v = v.to_string();
29        if let Some((status, info)) = v.split_once(' ') {
30            let status = style(status).cyan().bold();
31            eprintln!("{status:>12} {info}")
32        } else {
33            eprintln!("{v}");
34        }
35        Self { start_time }
36    }
37
38    pub fn finish<T: fmt::Display>(self, v: T) {
39        let total = self.total_time();
40        let total = style(&total).dim();
41
42        let v = v.to_string();
43        if let Some((status, info)) = v.split_once(' ') {
44            let status = style(status).green().bold();
45            eprintln!("{status:>12} {info} {total}")
46        } else {
47            eprintln!("{v} {total}");
48        }
49    }
50
51    fn total_time(&self) -> String {
52        if *INTERNAL_CI {
53            return String::new();
54        }
55
56        let total = self.start_time.elapsed();
57
58        if total.as_secs() > 0 {
59            format!("{:.2}s", total.as_secs_f32())
60        } else if total.as_millis() > 0 {
61            format!("{}ms", total.as_millis())
62        } else if total.as_micros() > 0 {
63            format!("{}µs", total.as_micros())
64        } else {
65            format!("{total:?}")
66        }
67    }
68}