xref: /aosp_15_r20/tools/asuite/adevice/src/progress.rs (revision c2e18aaa1096c836b086f94603d04f4eb9cf37f5)
1 use std::io::{self, Write};
2 use std::sync::{Arc, LazyLock, Mutex};
3 use std::thread;
4 use std::time::{Duration, Instant};
5 
6 static PROGRESS: LazyLock<Progress> = LazyLock::new(|| Progress {
7     message: Arc::new(Mutex::new("".to_string())),
8     is_complete: Arc::new(Mutex::new(false)),
9 });
10 
11 pub struct Progress {
12     message: Arc<Mutex<String>>,
13     is_complete: Arc<Mutex<bool>>,
14 }
15 
16 impl Progress {
start(&self)17     fn start(&self) {
18         let is_complete = self.is_complete.clone();
19         let message_ref = self.message.clone();
20         thread::spawn(move || {
21             let start = Instant::now();
22             while !*is_complete.lock().unwrap() {
23                 let minutes = start.elapsed().as_secs() / 60;
24                 let seconds = start.elapsed().as_secs() % 60;
25                 let mut message =
26                     format!("     {:01}:{:02} {}", minutes, seconds, message_ref.lock().unwrap());
27                 if message.len() > 80 {
28                     message.truncate(77);
29                     message.push('…');
30                 }
31                 print!("\x1B[2K"); // clear the line
32                 print!("\r{} ", message);
33                 io::stdout().flush().unwrap();
34                 thread::sleep(Duration::from_millis(100));
35             }
36             let mut complete = PROGRESS.is_complete.lock().unwrap();
37             *complete = false;
38         });
39     }
40 
stop(&self)41     fn stop(&self) {
42         let mut is_complete = self.is_complete.lock().unwrap();
43         *is_complete = true;
44         print!("\x1B[2K"); // clear the line
45         print!("\r");
46         io::stdout().flush().unwrap();
47     }
48 }
49 
update(message: &str)50 pub fn update(message: &str) {
51     let mut new_message = PROGRESS.message.lock().unwrap();
52     *new_message = message.to_string();
53 }
54 
start(message: &str)55 pub fn start(message: &str) {
56     update(message);
57     PROGRESS.start();
58 }
59 
stop()60 pub fn stop() {
61     PROGRESS.stop();
62 }
63