demo/
demo.rs

1use std::time::Duration;
2
3use cli_status_board::{SBState, SBStateConfig, Status, TaskNameWidth};
4
5fn main() {
6    let state = SBState::new(SBStateConfig {
7        silent: false,
8        task_name_width: TaskNameWidth::ExactRatio(0.25),
9        grow_if_no_progress: false,
10        ..Default::default()
11    });
12
13    // The handles for these tasks are immediately dropped, so we automatically remove them.
14    // Except for error/info, which we display for a little while before removing automatically.
15    {
16        {
17            let task_id = state.add_task("finished task", Status::Finished);
18            state.add_subtask(&task_id, Status::Started);
19        }
20        let _ = state.add_task("error task", Status::Error);
21        let _ = state.add_task("started task", Status::Started);
22        let _ = state.add_task("queued task", Status::Queued);
23    }
24
25    let mut tasks = (0..10)
26        .into_iter()
27        .map(|index| {
28            let state = state.clone();
29            std::thread::spawn(move || {
30                std::thread::sleep(Duration::from_secs(index));
31                let task_id = state.add_task(format!("Task {index}"), Status::Started);
32                std::thread::sleep(Duration::from_secs(index.min(3)));
33                let sub_tasks = (0..10)
34                    .into_iter()
35                    .map(|_| state.add_subtask(&task_id, Status::Started))
36                    .collect::<Vec<_>>();
37
38                for sub_task_id in sub_tasks {
39                    std::thread::sleep(Duration::from_secs((index + 1).min(3)));
40                    state.update_subtask(&task_id, &sub_task_id, Status::Finished);
41                }
42
43                state.update_task(&task_id, Status::Finished);
44            })
45        })
46        .collect::<Vec<_>>();
47
48    tasks.push(std::thread::spawn({
49        let state = state.clone();
50        move || {
51            let task_id = state.add_task(
52                format!("Task with looooooooooooooooooooooooooooooooooooooong message. I mean, it's soooooooooooooooooooooooooooooooo loooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnngggggggggggggggggg"),
53                Status::Started,
54            );
55            std::thread::sleep(Duration::from_secs(10));
56            state.update_task(&task_id, Status::Finished);
57        }
58    }));
59
60    tasks.push(std::thread::spawn({
61        let state = state.clone();
62        move || {
63            let task_id = state.add_task(format!("Task with no children"), Status::Started);
64            std::thread::sleep(Duration::from_secs(10));
65            state.update_task(&task_id, Status::Finished);
66        }
67    }));
68
69    tasks.push(std::thread::spawn(move || {
70        std::thread::sleep(Duration::from_secs(4));
71        state.info("Here's an informational message");
72        std::thread::sleep(Duration::from_secs(8));
73        state.info("Here's another one :)");
74    }));
75
76    for task in tasks {
77        task.join().unwrap();
78    }
79}