| 71 | } |
| 72 | |
| 73 | pub fn print( |
| 74 | stdout: &mut Stdout, |
| 75 | progress_lines: u16, |
| 76 | lines: Vec<String>, |
| 77 | bars: &HashMap<String, BarData>, |
| 78 | last: bool, |
| 79 | ) -> anyhow::Result<()> { |
| 80 | let (_, height) = terminal::size()?; |
| 81 | |
| 82 | execute!( |
| 83 | stdout, |
| 84 | MoveTo(0, height - progress_lines as u16), |
| 85 | Clear(ClearType::FromCursorDown), |
| 86 | MoveUp(1), |
| 87 | )?; |
| 88 | |
| 89 | for line in lines { |
| 90 | let (_, y) = cursor::position()?; |
| 91 | execute!(stdout, Print(line))?; |
| 92 | let (_, new_y) = cursor::position()?; |
| 93 | let n = new_y - y; |
| 94 | execute!(stdout, ScrollUp(n), MoveUp(n))?; |
| 95 | } |
| 96 | |
| 97 | execute!( |
| 98 | stdout, |
| 99 | MoveTo(0, height - progress_lines as u16 + 1), |
| 100 | Clear(ClearType::FromCursorDown), |
| 101 | MoveUp(1), |
| 102 | )?; |
| 103 | |
| 104 | for (_, bar) in bars { |
| 105 | if bar.done { |
| 106 | execute!( |
| 107 | stdout, |
| 108 | Print(format!("{}: Done", bar.worker_name,)), |
| 109 | MoveToNextLine(1), |
| 110 | )?; |
| 111 | } else { |
| 112 | let progress_percentage = bar.duration.as_secs_f64() |
| 113 | / (bar.duration.as_secs_f64() + bar.left.as_secs_f64()) |
| 114 | * 100 as f64; |
| 115 | execute!( |
| 116 | stdout, |
| 117 | Print(format!( |
| 118 | "{}: [{: <25}] {:.2}% ({}/{})", |
| 119 | bar.worker_name, |
| 120 | "*".repeat((progress_percentage as usize) / 4), |
| 121 | progress_percentage, |
| 122 | bar.active_vus, |
| 123 | bar.all_vus, |
| 124 | )), |
| 125 | MoveToNextLine(1), |
| 126 | )?; |
| 127 | } |
| 128 | } |
| 129 | if last { |
| 130 | execute!(stdout, Print("\n"),)?; |