From 1953c8bb8b7ec3a84e1b238421c0320f9e0b3391 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sun, 26 Apr 2020 14:12:06 +0100 Subject: Working implementation of the elapsed time of the capture This elapsed time pauses during pause sections and restarts on resumption. Ongoing: - Consider a RwLock instead of a Mutex for the elapsed time and cumulative time values, as these are only written by the UI thread and read elsewhere. - Combine the cumulative time and start times into a struct for clarity. - Separate out the elapsed time from the Bandwidth, as they are separate considerations, leading to altering the rendering of the header to write bandwidth and elapsed time separately. --- src/display/components/total_bandwidth.rs | 15 +++++++++++++++ src/display/ui.rs | 3 ++- src/main.rs | 30 +++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 80d892f..311ce67 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -8,6 +8,7 @@ use crate::display::{DisplayBandwidth, UIState}; pub struct TotalBandwidth<'a> { pub state: &'a UIState, + pub elapsed_time: std::time::Duration, pub paused: bool, } @@ -38,8 +39,22 @@ impl<'a> TotalBandwidth<'a> { Style::default().fg(color).modifier(Modifier::BOLD), )] }; + Paragraph::new(title_text.iter()) .alignment(Alignment::Left) .render(frame, rect); + + let elapsed_time_text = [Text::styled( + format!( + "Total Elapsed Time: {:02}:{:02}:{:02}", + self.elapsed_time.as_secs() / 3600, + (self.elapsed_time.as_secs() % 3600) / 60, + self.elapsed_time.as_secs() % 60 + ), + Style::default().fg(Color::LightBlue).modifier(Modifier::BOLD), + )]; + Paragraph::new(elapsed_time_text.iter()) + .alignment(Alignment::Right) + .render(frame, rect); } } diff --git a/src/display/ui.rs b/src/display/ui.rs index 68f133a..cd87786 100644 --- a/src/display/ui.rs +++ b/src/display/ui.rs @@ -79,7 +79,7 @@ where )); } } - pub fn draw(&mut self, paused: bool, show_dns: bool) { + pub fn draw(&mut self, paused: bool, show_dns: bool, elapsed_time: std::time::Duration) { let state = &self.state; let children = self.get_tables_to_display(); self.terminal @@ -87,6 +87,7 @@ where let size = frame.size(); let total_bandwidth = TotalBandwidth { state: &state, + elapsed_time, paused, }; let help_text = HelpText { paused, show_dns }; diff --git a/src/main.rs b/src/main.rs index d91430a..50cdf16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -121,6 +121,8 @@ where { let running = Arc::new(AtomicBool::new(true)); let paused = Arc::new(AtomicBool::new(false)); + let last_start_time = Arc::new(Mutex::new(Instant::now())); + let cumulative_time = Arc::new(Mutex::new(std::time::Duration::new(0, 0))); let dns_shown = opts.show_dns; let mut active_threads = vec![]; @@ -148,7 +150,7 @@ where on_winch({ Box::new(move || { let mut ui = ui.lock().unwrap(); - ui.draw(paused.load(Ordering::SeqCst), dns_shown); + ui.draw(paused.load(Ordering::SeqCst), dns_shown, std::time::Duration::new(131, 0)); }) }); } @@ -163,6 +165,9 @@ where let running = running.clone(); let paused = paused.clone(); let network_utilization = network_utilization.clone(); + let last_start_time = last_start_time.clone(); + let cumulative_time = cumulative_time.clone(); + move || { while running.load(Ordering::Acquire) { let render_start_time = Instant::now(); @@ -188,10 +193,16 @@ where if !paused { ui.update_state(sockets_to_procs, utilization, ip_to_host); } + let elapsed_time = if paused { + cumulative_time.lock().unwrap().clone() + } else { + *cumulative_time.lock().unwrap() + last_start_time.lock().unwrap().elapsed() + }; + if raw_mode { ui.output_text(&mut write_to_stdout); } else { - ui.draw(paused, dns_shown); + ui.draw(paused, dns_shown, elapsed_time); } } let render_duration = render_start_time.elapsed(); @@ -223,7 +234,20 @@ where break; } Event::Key(Key::Char(' ')) => { - paused.fetch_xor(true, Ordering::SeqCst); + let restarting = paused.fetch_xor(true, Ordering::SeqCst); + if restarting { + *last_start_time.lock().unwrap() = Instant::now(); + } else { + let last_start_time_clone = { + last_start_time.lock().unwrap().clone() + }; + let current_cumulative_time_clone = { + cumulative_time.lock().unwrap().clone() + }; + let new_cumulative_time = current_cumulative_time_clone + last_start_time_clone.elapsed(); + *cumulative_time.lock().unwrap() = new_cumulative_time; + } + display_handler.unpark(); } _ => (), -- cgit v1.2.3 From 5cb0c7690a098c40400f7d3ca18db789eadaeb5f Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sun, 26 Apr 2020 14:15:11 +0100 Subject: Running cargo fmt --- src/display/components/total_bandwidth.rs | 8 +++++--- src/main.rs | 22 +++++++++++++--------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 311ce67..844fb2a 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -51,10 +51,12 @@ impl<'a> TotalBandwidth<'a> { (self.elapsed_time.as_secs() % 3600) / 60, self.elapsed_time.as_secs() % 60 ), - Style::default().fg(Color::LightBlue).modifier(Modifier::BOLD), + Style::default() + .fg(Color::LightBlue) + .modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) - .alignment(Alignment::Right) - .render(frame, rect); + .alignment(Alignment::Right) + .render(frame, rect); } } diff --git a/src/main.rs b/src/main.rs index 50cdf16..d4dfb31 100644 --- a/src/main.rs +++ b/src/main.rs @@ -150,7 +150,11 @@ where on_winch({ Box::new(move || { let mut ui = ui.lock().unwrap(); - ui.draw(paused.load(Ordering::SeqCst), dns_shown, std::time::Duration::new(131, 0)); + ui.draw( + paused.load(Ordering::SeqCst), + dns_shown, + std::time::Duration::new(131, 0), + ); }) }); } @@ -196,7 +200,8 @@ where let elapsed_time = if paused { cumulative_time.lock().unwrap().clone() } else { - *cumulative_time.lock().unwrap() + last_start_time.lock().unwrap().elapsed() + *cumulative_time.lock().unwrap() + + last_start_time.lock().unwrap().elapsed() }; if raw_mode { @@ -238,13 +243,12 @@ where if restarting { *last_start_time.lock().unwrap() = Instant::now(); } else { - let last_start_time_clone = { - last_start_time.lock().unwrap().clone() - }; - let current_cumulative_time_clone = { - cumulative_time.lock().unwrap().clone() - }; - let new_cumulative_time = current_cumulative_time_clone + last_start_time_clone.elapsed(); + let last_start_time_clone = + { last_start_time.lock().unwrap().clone() }; + let current_cumulative_time_clone = + { cumulative_time.lock().unwrap().clone() }; + let new_cumulative_time = current_cumulative_time_clone + + last_start_time_clone.elapsed(); *cumulative_time.lock().unwrap() = new_cumulative_time; } -- cgit v1.2.3 From 8a2469f4ec340cb6104db6ef488438649f0c1d27 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sun, 26 Apr 2020 19:36:02 +0100 Subject: Split Header rendering into different sections - Rename Bandwidth to HeaderDetails to indicate the added information it now contains. - Split the rendering function for the header into its constituent parts --- src/display/components/layout.rs | 4 ++-- src/display/components/total_bandwidth.rs | 23 +++++++++++++++-------- src/display/ui.rs | 4 ++-- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/display/components/layout.rs b/src/display/components/layout.rs index c047774..c86211a 100644 --- a/src/display/components/layout.rs +++ b/src/display/components/layout.rs @@ -4,7 +4,7 @@ use ::tui::terminal::Frame; use super::HelpText; use super::Table; -use super::TotalBandwidth; +use super::HeaderDetails; const FIRST_HEIGHT_BREAKPOINT: u16 = 30; const FIRST_WIDTH_BREAKPOINT: u16 = 120; @@ -26,7 +26,7 @@ fn top_app_and_bottom_split(rect: Rect) -> (Rect, Rect, Rect) { } pub struct Layout<'a> { - pub header: TotalBandwidth<'a>, + pub header: HeaderDetails<'a>, pub children: Vec>, pub footer: HelpText, } diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 844fb2a..a1968e5 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -6,14 +6,19 @@ use ::tui::widgets::{Paragraph, Text, Widget}; use crate::display::{DisplayBandwidth, UIState}; -pub struct TotalBandwidth<'a> { +pub struct HeaderDetails<'a> { pub state: &'a UIState, pub elapsed_time: std::time::Duration, pub paused: bool, } -impl<'a> TotalBandwidth<'a> { +impl<'a> HeaderDetails<'a> { pub fn render(&self, frame: &mut Frame, rect: Rect) { + self.render_bandwidth(frame, rect); + self.render_elapsed_time(frame, rect); + } + + fn render_bandwidth(&self, frame: &mut Frame, rect: Rect) { let c_mode = self.state.cumulative_mode; let title_text = { let paused_str = if self.paused { "[PAUSED]" } else { "" }; @@ -41,9 +46,11 @@ impl<'a> TotalBandwidth<'a> { }; Paragraph::new(title_text.iter()) - .alignment(Alignment::Left) - .render(frame, rect); + .alignment(Alignment::Left) + .render(frame, rect); + } + fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect) { let elapsed_time_text = [Text::styled( format!( "Total Elapsed Time: {:02}:{:02}:{:02}", @@ -52,11 +59,11 @@ impl<'a> TotalBandwidth<'a> { self.elapsed_time.as_secs() % 60 ), Style::default() - .fg(Color::LightBlue) - .modifier(Modifier::BOLD), + .fg(Color::LightBlue) + .modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) - .alignment(Alignment::Right) - .render(frame, rect); + .alignment(Alignment::Right) + .render(frame, rect); } } diff --git a/src/display/ui.rs b/src/display/ui.rs index cd87786..21ae49d 100644 --- a/src/display/ui.rs +++ b/src/display/ui.rs @@ -3,7 +3,7 @@ use ::std::collections::HashMap; use ::tui::backend::Backend; use ::tui::Terminal; -use crate::display::components::{HelpText, Layout, Table, TotalBandwidth}; +use crate::display::components::{HelpText, Layout, Table, HeaderDetails}; use crate::display::UIState; use crate::network::{display_connection_string, display_ip_or_host, LocalSocket, Utilization}; @@ -85,7 +85,7 @@ where self.terminal .draw(|mut frame| { let size = frame.size(); - let total_bandwidth = TotalBandwidth { + let total_bandwidth = HeaderDetails { state: &state, elapsed_time, paused, -- cgit v1.2.3 From 265390b574c350be24c95e67a9ea733a1134e889 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sun, 26 Apr 2020 19:52:23 +0100 Subject: Change from Mutex to RwLock around elapsed time variables A RwLock should be more performant. --- src/main.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index d4dfb31..d12f946 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,6 +29,7 @@ use ::std::time::Instant; use ::termion::raw::IntoRawMode; use ::tui::backend::TermionBackend; use structopt::StructOpt; +use std::sync::RwLock; const DISPLAY_DELTA: time::Duration = time::Duration::from_millis(1000); @@ -121,8 +122,8 @@ where { let running = Arc::new(AtomicBool::new(true)); let paused = Arc::new(AtomicBool::new(false)); - let last_start_time = Arc::new(Mutex::new(Instant::now())); - let cumulative_time = Arc::new(Mutex::new(std::time::Duration::new(0, 0))); + let last_start_time = Arc::new(RwLock::new(Instant::now())); + let cumulative_time = Arc::new(RwLock::new(std::time::Duration::new(0, 0))); let dns_shown = opts.show_dns; let mut active_threads = vec![]; @@ -198,10 +199,10 @@ where ui.update_state(sockets_to_procs, utilization, ip_to_host); } let elapsed_time = if paused { - cumulative_time.lock().unwrap().clone() + *cumulative_time.read().unwrap() } else { - *cumulative_time.lock().unwrap() - + last_start_time.lock().unwrap().elapsed() + *cumulative_time.read().unwrap() + + last_start_time.read().unwrap().elapsed() }; if raw_mode { @@ -241,15 +242,13 @@ where Event::Key(Key::Char(' ')) => { let restarting = paused.fetch_xor(true, Ordering::SeqCst); if restarting { - *last_start_time.lock().unwrap() = Instant::now(); + *last_start_time.write().unwrap() = Instant::now(); } else { - let last_start_time_clone = - { last_start_time.lock().unwrap().clone() }; - let current_cumulative_time_clone = - { cumulative_time.lock().unwrap().clone() }; - let new_cumulative_time = current_cumulative_time_clone - + last_start_time_clone.elapsed(); - *cumulative_time.lock().unwrap() = new_cumulative_time; + let last_start_time_copy = *last_start_time.read().unwrap(); + let current_cumulative_time_copy = *cumulative_time.read().unwrap(); + let new_cumulative_time = current_cumulative_time_copy + + last_start_time_copy.elapsed(); + *cumulative_time.write().unwrap() = new_cumulative_time; } display_handler.unpark(); -- cgit v1.2.3 From 4844693ceac387fddfe18b01f9b975626ae47619 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sun, 26 Apr 2020 20:30:14 +0100 Subject: Running cargo fmt --- src/display/components/layout.rs | 2 +- src/display/components/total_bandwidth.rs | 12 ++++++------ src/display/ui.rs | 3 ++- src/main.rs | 5 +++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/display/components/layout.rs b/src/display/components/layout.rs index c86211a..6c9812d 100644 --- a/src/display/components/layout.rs +++ b/src/display/components/layout.rs @@ -2,9 +2,9 @@ use ::tui::backend::Backend; use ::tui::layout::{Constraint, Direction, Rect}; use ::tui::terminal::Frame; +use super::HeaderDetails; use super::HelpText; use super::Table; -use super::HeaderDetails; const FIRST_HEIGHT_BREAKPOINT: u16 = 30; const FIRST_WIDTH_BREAKPOINT: u16 = 120; diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index a1968e5..095247b 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -46,8 +46,8 @@ impl<'a> HeaderDetails<'a> { }; Paragraph::new(title_text.iter()) - .alignment(Alignment::Left) - .render(frame, rect); + .alignment(Alignment::Left) + .render(frame, rect); } fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect) { @@ -59,11 +59,11 @@ impl<'a> HeaderDetails<'a> { self.elapsed_time.as_secs() % 60 ), Style::default() - .fg(Color::LightBlue) - .modifier(Modifier::BOLD), + .fg(Color::LightBlue) + .modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) - .alignment(Alignment::Right) - .render(frame, rect); + .alignment(Alignment::Right) + .render(frame, rect); } } diff --git a/src/display/ui.rs b/src/display/ui.rs index 21ae49d..54db7fb 100644 --- a/src/display/ui.rs +++ b/src/display/ui.rs @@ -3,7 +3,7 @@ use ::std::collections::HashMap; use ::tui::backend::Backend; use ::tui::Terminal; -use crate::display::components::{HelpText, Layout, Table, HeaderDetails}; +use crate::display::components::{HeaderDetails, HelpText, Layout, Table}; use crate::display::UIState; use crate::network::{display_connection_string, display_ip_or_host, LocalSocket, Utilization}; @@ -79,6 +79,7 @@ where )); } } + pub fn draw(&mut self, paused: bool, show_dns: bool, elapsed_time: std::time::Duration) { let state = &self.state; let children = self.get_tables_to_display(); diff --git a/src/main.rs b/src/main.rs index d12f946..0ecd3ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,8 +28,8 @@ use ::std::io; use ::std::time::Instant; use ::termion::raw::IntoRawMode; use ::tui::backend::TermionBackend; -use structopt::StructOpt; use std::sync::RwLock; +use structopt::StructOpt; const DISPLAY_DELTA: time::Duration = time::Duration::from_millis(1000); @@ -245,7 +245,8 @@ where *last_start_time.write().unwrap() = Instant::now(); } else { let last_start_time_copy = *last_start_time.read().unwrap(); - let current_cumulative_time_copy = *cumulative_time.read().unwrap(); + let current_cumulative_time_copy = + *cumulative_time.read().unwrap(); let new_cumulative_time = current_cumulative_time_copy + last_start_time_copy.elapsed(); *cumulative_time.write().unwrap() = new_cumulative_time; -- cgit v1.2.3 From 1e7e0e47445557cf133fb16ce6f3ffa89e296249 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sun, 26 Apr 2020 20:31:22 +0100 Subject: Add space to elapsed time to mirror other print The bandwidth print has a leading space, so this should have a trailing space. --- src/display/components/total_bandwidth.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 095247b..0581330 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -53,7 +53,7 @@ impl<'a> HeaderDetails<'a> { fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect) { let elapsed_time_text = [Text::styled( format!( - "Total Elapsed Time: {:02}:{:02}:{:02}", + "Total Elapsed Time: {:02}:{:02}:{:02} ", self.elapsed_time.as_secs() / 3600, (self.elapsed_time.as_secs() % 3600) / 60, self.elapsed_time.as_secs() % 60 -- cgit v1.2.3 From 598239a3bcfee96545bc5364a4141f9131fada2a Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Fri, 8 May 2020 11:54:30 +0100 Subject: Address PR feedback. - Only show the capture time on use of the utilization flag - Make colour consistent in header - Prioritize rendering of the Bandwidth over the duration - Reduce length of time description --- src/display/components/total_bandwidth.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 0581330..dbc2e78 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -14,19 +14,19 @@ pub struct HeaderDetails<'a> { impl<'a> HeaderDetails<'a> { pub fn render(&self, frame: &mut Frame, rect: Rect) { - self.render_bandwidth(frame, rect); - self.render_elapsed_time(frame, rect); + let color = if self.paused { + Color::Yellow + } else { + Color::Green + }; + if self.state.cumulative_mode { self.render_elapsed_time(frame, rect, &color) }; + self.render_bandwidth(frame, rect, &color); } - fn render_bandwidth(&self, frame: &mut Frame, rect: Rect) { + fn render_bandwidth(&self, frame: &mut Frame, rect: Rect, color: &Color) { let c_mode = self.state.cumulative_mode; let title_text = { let paused_str = if self.paused { "[PAUSED]" } else { "" }; - let color = if self.paused { - Color::Yellow - } else { - Color::Green - }; [Text::styled( format!( @@ -41,7 +41,7 @@ impl<'a> HeaderDetails<'a> { }, paused_str ), - Style::default().fg(color).modifier(Modifier::BOLD), + Style::default().fg(*color).modifier(Modifier::BOLD), )] }; @@ -50,16 +50,16 @@ impl<'a> HeaderDetails<'a> { .render(frame, rect); } - fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect) { + fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect, color: &Color) { let elapsed_time_text = [Text::styled( format!( - "Total Elapsed Time: {:02}:{:02}:{:02} ", + "Duration: {:02}:{:02}:{:02} ", self.elapsed_time.as_secs() / 3600, (self.elapsed_time.as_secs() % 3600) / 60, self.elapsed_time.as_secs() % 60 ), Style::default() - .fg(Color::LightBlue) + .fg(*color) .modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) -- cgit v1.2.3 From a177280040ff6b93ed7660054f456f614d825a07 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 9 May 2020 15:48:11 +0100 Subject: Split the header row into 3 columns We now have the bandwidth data, paused status and duration in separate columns. --- src/display/components/layout.rs | 1 + src/display/components/total_bandwidth.rs | 45 ++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/display/components/layout.rs b/src/display/components/layout.rs index 6c9812d..d3edb81 100644 --- a/src/display/components/layout.rs +++ b/src/display/components/layout.rs @@ -99,6 +99,7 @@ impl<'a> Layout<'a> { self.build_three_children_layout(rect) } } + pub fn render(&self, frame: &mut Frame, rect: Rect) { let (top, app, bottom) = top_app_and_bottom_split(rect); let layout_slots = self.build_layout(app); diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index dbc2e78..3da80cd 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -5,6 +5,7 @@ use ::tui::terminal::Frame; use ::tui::widgets::{Paragraph, Text, Widget}; use crate::display::{DisplayBandwidth, UIState}; +use tui::layout::{Constraint, Direction}; pub struct HeaderDetails<'a> { pub state: &'a UIState, @@ -14,23 +15,38 @@ pub struct HeaderDetails<'a> { impl<'a> HeaderDetails<'a> { pub fn render(&self, frame: &mut Frame, rect: Rect) { + let parts = ::tui::layout::Layout::default() + .direction(Direction::Horizontal) + .margin(0) + .constraints( + [ + Constraint::Percentage(33), + Constraint::Percentage(33), + Constraint::Percentage(33), + ] + .as_ref(), + ) + .split(rect); + let color = if self.paused { Color::Yellow } else { Color::Green }; - if self.state.cumulative_mode { self.render_elapsed_time(frame, rect, &color) }; - self.render_bandwidth(frame, rect, &color); + + if self.state.cumulative_mode { + self.render_elapsed_time(frame, parts[2], &color) + }; + self.render_paused(frame, parts[1], &color); + self.render_bandwidth(frame, parts[0], &color); } fn render_bandwidth(&self, frame: &mut Frame, rect: Rect, color: &Color) { let c_mode = self.state.cumulative_mode; let title_text = { - let paused_str = if self.paused { "[PAUSED]" } else { "" }; - [Text::styled( format!( - " Total Up / Down: {} / {} {}", + " Total Up / Down: {} / {}", DisplayBandwidth { bandwidth: self.state.total_bytes_uploaded as f64, as_rate: !c_mode, @@ -38,8 +54,7 @@ impl<'a> HeaderDetails<'a> { DisplayBandwidth { bandwidth: self.state.total_bytes_downloaded as f64, as_rate: !c_mode, - }, - paused_str + } ), Style::default().fg(*color).modifier(Modifier::BOLD), )] @@ -58,12 +73,22 @@ impl<'a> HeaderDetails<'a> { (self.elapsed_time.as_secs() % 3600) / 60, self.elapsed_time.as_secs() % 60 ), - Style::default() - .fg(*color) - .modifier(Modifier::BOLD), + Style::default().fg(*color).modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) .alignment(Alignment::Right) .render(frame, rect); } + + fn render_paused(&self, frame: &mut Frame, rect: Rect, color: &Color) { + if self.paused { + let paused_text = [Text::styled( + format!("PAUSED"), + Style::default().fg(*color).modifier(Modifier::BOLD), + )]; + Paragraph::new(paused_text.iter()) + .alignment(Alignment::Center) + .render(frame, rect); + } + } } -- cgit v1.2.3 From da17936d5c638f2d15004f475b64a417191c8f3c Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 9 May 2020 16:55:24 +0100 Subject: Split the header into different parts based on size of terminal 1, 2, or 3 sections will be used based on differing widths. --- src/display/components/total_bandwidth.rs | 47 ++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 3da80cd..7c4bf44 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -15,18 +15,7 @@ pub struct HeaderDetails<'a> { impl<'a> HeaderDetails<'a> { pub fn render(&self, frame: &mut Frame, rect: Rect) { - let parts = ::tui::layout::Layout::default() - .direction(Direction::Horizontal) - .margin(0) - .constraints( - [ - Constraint::Percentage(33), - Constraint::Percentage(33), - Constraint::Percentage(33), - ] - .as_ref(), - ) - .split(rect); + let parts = self.header_parts(rect); let color = if self.paused { Color::Yellow @@ -34,11 +23,15 @@ impl<'a> HeaderDetails<'a> { Color::Green }; - if self.state.cumulative_mode { - self.render_elapsed_time(frame, parts[2], &color) - }; - self.render_paused(frame, parts[1], &color); - self.render_bandwidth(frame, parts[0], &color); + if parts.get(0).is_some() { + self.render_bandwidth(frame, parts[0], &color); + } + if parts.get(1).is_some() { + self.render_paused(frame, parts[1], &color); + } + if parts.get(2).is_some() && self.state.cumulative_mode { + self.render_elapsed_time(frame, parts[2], &color); + } } fn render_bandwidth(&self, frame: &mut Frame, rect: Rect, color: &Color) { @@ -91,4 +84,24 @@ impl<'a> HeaderDetails<'a> { .render(frame, rect); } } + + fn header_parts(&self, rect: Rect) -> Vec { + let number = { + match rect.width { + 0..=62 => 1, + 63..=93 => 2, + _ => 3, + } + }; + + let constraints: Vec = (0..number) + .map(|_| Constraint::Percentage(100 / number)) + .collect(); + + ::tui::layout::Layout::default() + .direction(Direction::Horizontal) + .margin(0) + .constraints(constraints.as_ref()) + .split(rect) + } } -- cgit v1.2.3 From 0122bf351aefe55c568d24097b3f7eaa259ef041 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 9 May 2020 17:10:20 +0100 Subject: Simplify logic in the header_parts function --- src/display/components/total_bandwidth.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 7c4bf44..c9a9676 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -86,16 +86,10 @@ impl<'a> HeaderDetails<'a> { } fn header_parts(&self, rect: Rect) -> Vec { - let number = { - match rect.width { - 0..=62 => 1, - 63..=93 => 2, - _ => 3, - } - }; - - let constraints: Vec = (0..number) - .map(|_| Constraint::Percentage(100 / number)) + const MAX_BANDWIDTH_STRING_LENGTH: u16 = 31; + let number_of_columns = rect.width / MAX_BANDWIDTH_STRING_LENGTH; + let constraints: Vec = (0..number_of_columns) + .map(|_| Constraint::Percentage(100 / number_of_columns)) .collect(); ::tui::layout::Layout::default() -- cgit v1.2.3 From 53b80c7175a42dc5dd4b6b3ead65fc107c2f532e Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 9 May 2020 17:23:43 +0100 Subject: Fix silly issue with altering logic - Needed to set max number of columns to 3. --- src/display/components/total_bandwidth.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index c9a9676..8a16b3e 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -87,7 +87,10 @@ impl<'a> HeaderDetails<'a> { fn header_parts(&self, rect: Rect) -> Vec { const MAX_BANDWIDTH_STRING_LENGTH: u16 = 31; - let number_of_columns = rect.width / MAX_BANDWIDTH_STRING_LENGTH; + let number_of_columns = *[3, rect.width / MAX_BANDWIDTH_STRING_LENGTH] + .iter() + .min() + .unwrap(); let constraints: Vec = (0..number_of_columns) .map(|_| Constraint::Percentage(100 / number_of_columns)) .collect(); -- cgit v1.2.3 From e17f8e624299463fe1174f55264df39569e83863 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 9 May 2020 17:24:13 +0100 Subject: Add days to the duration print --- src/display/components/total_bandwidth.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 8a16b3e..93e8671 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -59,9 +59,17 @@ impl<'a> HeaderDetails<'a> { } fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect, color: &Color) { + const SECONDS_IN_DAY: u64 = 86400; + let plural = if self.elapsed_time.as_secs() / SECONDS_IN_DAY == 1 { + "" + } else { + "s" + }; let elapsed_time_text = [Text::styled( format!( - "Duration: {:02}:{:02}:{:02} ", + "{:01} day{}, {:02}:{:02}:{:02} ", + self.elapsed_time.as_secs() / SECONDS_IN_DAY, + plural, self.elapsed_time.as_secs() / 3600, (self.elapsed_time.as_secs() % 3600) / 60, self.elapsed_time.as_secs() % 60 -- cgit v1.2.3 From bc0db53b4e0bd01520ae7631874901168cc5530a Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 16 May 2020 17:23:08 +0100 Subject: Address review feedback Now selectively printing out the duration of the capture based on calculating the exact length of the strings and the width of the terminal window. This has simplified this code substantially as well, no longer having to split the header into parts (currently we are printing to the same rect, but left and right aligned for the respective parts of the header). --- src/display/components/total_bandwidth.rs | 103 ++++++++++++------------------ 1 file changed, 41 insertions(+), 62 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 93e8671..5f3a3f7 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -5,7 +5,8 @@ use ::tui::terminal::Frame; use ::tui::widgets::{Paragraph, Text, Widget}; use crate::display::{DisplayBandwidth, UIState}; -use tui::layout::{Constraint, Direction}; + +const SECONDS_IN_DAY: u64 = 86400; pub struct HeaderDetails<'a> { pub state: &'a UIState, @@ -15,7 +16,9 @@ pub struct HeaderDetails<'a> { impl<'a> HeaderDetails<'a> { pub fn render(&self, frame: &mut Frame, rect: Rect) { - let parts = self.header_parts(rect); + let bandwidth = self.bandwidth_string(); + let elapsed_time = self.elapsed_time_string(); + let print_elapsed_time = bandwidth.len() + elapsed_time.len() + 1 <= rect.width as usize; let color = if self.paused { Color::Yellow @@ -23,57 +26,44 @@ impl<'a> HeaderDetails<'a> { Color::Green }; - if parts.get(0).is_some() { - self.render_bandwidth(frame, parts[0], &color); - } - if parts.get(1).is_some() { - self.render_paused(frame, parts[1], &color); - } - if parts.get(2).is_some() && self.state.cumulative_mode { - self.render_elapsed_time(frame, parts[2], &color); + if print_elapsed_time { + self.render_elapsed_time(frame, rect, &color); } + self.render_bandwidth(frame, rect, &color); } fn render_bandwidth(&self, frame: &mut Frame, rect: Rect, color: &Color) { - let c_mode = self.state.cumulative_mode; - let title_text = { + let bandwidth_text = { [Text::styled( - format!( - " Total Up / Down: {} / {}", - DisplayBandwidth { - bandwidth: self.state.total_bytes_uploaded as f64, - as_rate: !c_mode, - }, - DisplayBandwidth { - bandwidth: self.state.total_bytes_downloaded as f64, - as_rate: !c_mode, - } - ), + self.bandwidth_string(), Style::default().fg(*color).modifier(Modifier::BOLD), )] }; - Paragraph::new(title_text.iter()) + Paragraph::new(bandwidth_text.iter()) .alignment(Alignment::Left) .render(frame, rect); } + fn bandwidth_string(&self) -> String { + let c_mode = self.state.cumulative_mode; + format!( + " Total Up / Down: {} / {}{}", + DisplayBandwidth { + bandwidth: self.state.total_bytes_uploaded as f64, + as_rate: !c_mode, + }, + DisplayBandwidth { + bandwidth: self.state.total_bytes_downloaded as f64, + as_rate: !c_mode, + }, + if self.paused { " [PAUSED]" } else { "" } + ) + } + fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect, color: &Color) { - const SECONDS_IN_DAY: u64 = 86400; - let plural = if self.elapsed_time.as_secs() / SECONDS_IN_DAY == 1 { - "" - } else { - "s" - }; let elapsed_time_text = [Text::styled( - format!( - "{:01} day{}, {:02}:{:02}:{:02} ", - self.elapsed_time.as_secs() / SECONDS_IN_DAY, - plural, - self.elapsed_time.as_secs() / 3600, - (self.elapsed_time.as_secs() % 3600) / 60, - self.elapsed_time.as_secs() % 60 - ), + self.elapsed_time_string(), Style::default().fg(*color).modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) @@ -81,32 +71,21 @@ impl<'a> HeaderDetails<'a> { .render(frame, rect); } - fn render_paused(&self, frame: &mut Frame, rect: Rect, color: &Color) { - if self.paused { - let paused_text = [Text::styled( - format!("PAUSED"), - Style::default().fg(*color).modifier(Modifier::BOLD), - )]; - Paragraph::new(paused_text.iter()) - .alignment(Alignment::Center) - .render(frame, rect); + fn days_string(&self) -> String { + match self.elapsed_time.as_secs() / SECONDS_IN_DAY { + 0 => "".to_string(), + 1 => "1 day, ".to_string(), + n => format!("{} days, ", n) } } - fn header_parts(&self, rect: Rect) -> Vec { - const MAX_BANDWIDTH_STRING_LENGTH: u16 = 31; - let number_of_columns = *[3, rect.width / MAX_BANDWIDTH_STRING_LENGTH] - .iter() - .min() - .unwrap(); - let constraints: Vec = (0..number_of_columns) - .map(|_| Constraint::Percentage(100 / number_of_columns)) - .collect(); - - ::tui::layout::Layout::default() - .direction(Direction::Horizontal) - .margin(0) - .constraints(constraints.as_ref()) - .split(rect) + fn elapsed_time_string(&self) -> String { + format!( + "{}{:02}:{:02}:{:02} ", + self.days_string(), + (self.elapsed_time.as_secs() % SECONDS_IN_DAY) / 3600, + (self.elapsed_time.as_secs() % 3600) / 60, + self.elapsed_time.as_secs() % 60 + ) } } -- cgit v1.2.3 From 24934963d282e854b901c073228589eaf75bdde3 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 16 May 2020 17:55:46 +0100 Subject: Fix issue of duration being shown on non -t invocations --- src/display/components/total_bandwidth.rs | 35 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index 5f3a3f7..e38d5e4 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -17,8 +17,13 @@ pub struct HeaderDetails<'a> { impl<'a> HeaderDetails<'a> { pub fn render(&self, frame: &mut Frame, rect: Rect) { let bandwidth = self.bandwidth_string(); - let elapsed_time = self.elapsed_time_string(); - let print_elapsed_time = bandwidth.len() + elapsed_time.len() + 1 <= rect.width as usize; + let mut elapsed_time = None; + let mut print_elapsed_time = false; + if self.state.cumulative_mode { + elapsed_time = Some(self.elapsed_time_string()); + print_elapsed_time = + bandwidth.len() + elapsed_time.as_ref().unwrap().len() + 1 <= rect.width as usize; + } let color = if self.paused { Color::Yellow @@ -27,15 +32,21 @@ impl<'a> HeaderDetails<'a> { }; if print_elapsed_time { - self.render_elapsed_time(frame, rect, &color); + self.render_elapsed_time(frame, rect, elapsed_time.as_ref().unwrap(), &color); } - self.render_bandwidth(frame, rect, &color); + self.render_bandwidth(frame, rect, &bandwidth, &color); } - fn render_bandwidth(&self, frame: &mut Frame, rect: Rect, color: &Color) { + fn render_bandwidth( + &self, + frame: &mut Frame, + rect: Rect, + bandwidth: &String, + color: &Color, + ) { let bandwidth_text = { [Text::styled( - self.bandwidth_string(), + bandwidth, Style::default().fg(*color).modifier(Modifier::BOLD), )] }; @@ -61,9 +72,15 @@ impl<'a> HeaderDetails<'a> { ) } - fn render_elapsed_time(&self, frame: &mut Frame, rect: Rect, color: &Color) { + fn render_elapsed_time( + &self, + frame: &mut Frame, + rect: Rect, + elapsed_time: &String, + color: &Color, + ) { let elapsed_time_text = [Text::styled( - self.elapsed_time_string(), + elapsed_time, Style::default().fg(*color).modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) @@ -75,7 +92,7 @@ impl<'a> HeaderDetails<'a> { match self.elapsed_time.as_secs() / SECONDS_IN_DAY { 0 => "".to_string(), 1 => "1 day, ".to_string(), - n => format!("{} days, ", n) + n => format!("{} days, ", n), } } -- cgit v1.2.3 From 07c734a90d4babca5eb9d93825deee0e8348d855 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 16 May 2020 18:03:19 +0100 Subject: Altering the snapshots for tests that are affected by new duration code Simply replacing the "1 \n" write events with "2 \n" when we check the snapshots to make them consistent. There may still be issues with timing in the tests, but can serve as a stop-gap. --- ...ined_traffic_from_multiple_processes_bi_directional_total-2.snap | 4 ++-- ...tained_traffic_from_multiple_processes_bi_directional_total.snap | 2 +- .../ui__sustained_traffic_from_multiple_processes_total-2.snap | 4 ++-- .../ui__sustained_traffic_from_multiple_processes_total.snap | 2 +- .../snapshots/ui__sustained_traffic_from_one_process_total-2.snap | 4 ++-- .../snapshots/ui__sustained_traffic_from_one_process_total.snap | 2 +- src/tests/cases/ui.rs | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total-2.snap b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total-2.snap index 62a5202..27a8b30 100644 --- a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total-2.snap +++ b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total-2.snap @@ -1,8 +1,8 @@ --- source: src/tests/cases/ui.rs -expression: "&terminal_draw_events_mirror[2]" +expression: "&terminal_draw_events_mirror[2].replace(\"1 \\n\", \"2 \\n\")" --- - 98 109B + 98 109B 2 diff --git a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total.snap b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total.snap index abe1164..81929e3 100644 --- a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total.snap +++ b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_bi_directional_total.snap @@ -2,7 +2,7 @@ source: src/tests/cases/ui.rs expression: "&terminal_draw_events_mirror[1]" --- - 45B / 49B + 45B / 49B 1 diff --git a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total-2.snap b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total-2.snap index 3fec816..cf6c136 100644 --- a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total-2.snap +++ b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total-2.snap @@ -1,8 +1,8 @@ --- source: src/tests/cases/ui.rs -expression: "&terminal_draw_events_mirror[2]" +expression: "&terminal_draw_events_mirror[2].replace(\"1 \\n\", \"2 \\n\")" --- - 106B + 106B 2 diff --git a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total.snap b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total.snap index 3012f6b..f09e329 100644 --- a/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total.snap +++ b/src/tests/cases/snapshots/ui__sustained_traffic_from_multiple_processes_total.snap @@ -2,7 +2,7 @@ source: src/tests/cases/ui.rs expression: "&terminal_draw_events_mirror[1]" --- - 41B + 41B 1 diff --git a/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total-2.snap b/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total-2.snap index b6456b7..8dfceee 100644 --- a/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total-2.snap +++ b/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total-2.snap @@ -1,8 +1,8 @@ --- source: src/tests/cases/ui.rs -expression: "&terminal_draw_events_mirror[2]" +expression: "&terminal_draw_events_mirror[2].replace(\"1 \\n\", \"2 \\n\")" --- - 53 + 53 2 diff --git a/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total.snap b/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total.snap index 8c590f5..3f5c319 100644 --- a/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total.snap +++ b/src/tests/cases/snapshots/ui__sustained_traffic_from_one_process_total.snap @@ -2,7 +2,7 @@ source: src/tests/cases/ui.rs expression: "&terminal_draw_events_mirror[1]" --- - 22B + 22B 1 diff --git a/src/tests/cases/ui.rs b/src/tests/cases/ui.rs index 824f55e..8125879 100644 --- a/src/tests/cases/ui.rs +++ b/src/tests/cases/ui.rs @@ -655,7 +655,7 @@ fn sustained_traffic_from_one_process_total() { assert_eq!(terminal_draw_events_mirror.len(), 3); assert_snapshot!(&terminal_draw_events_mirror[1]); - assert_snapshot!(&terminal_draw_events_mirror[2]); + assert_snapshot!(&terminal_draw_events_mirror[2].replace("1 \n", "2 \n")); } #[test] @@ -764,7 +764,7 @@ fn sustained_traffic_from_multiple_processes_total() { assert_eq!(terminal_draw_events_mirror.len(), 3); assert_snapshot!(&terminal_draw_events_mirror[1]); - assert_snapshot!(&terminal_draw_events_mirror[2]); + assert_snapshot!(&terminal_draw_events_mirror[2].replace("1 \n", "2 \n")); } #[test] @@ -929,7 +929,7 @@ fn sustained_traffic_from_multiple_processes_bi_directional_total() { assert_eq!(terminal_draw_events_mirror.len(), 3); assert_snapshot!(&terminal_draw_events_mirror[1]); - assert_snapshot!(&terminal_draw_events_mirror[2]); + assert_snapshot!(&terminal_draw_events_mirror[2].replace("1 \n", "2 \n")); } #[test] -- cgit v1.2.3 From edea995ce9337dff2df74acbe8833c6c926b0f8e Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Sat, 16 May 2020 18:30:51 +0100 Subject: Deal with clippy linting issues --- src/display/components/total_bandwidth.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs index e38d5e4..a3b0766 100644 --- a/src/display/components/total_bandwidth.rs +++ b/src/display/components/total_bandwidth.rs @@ -15,15 +15,16 @@ pub struct HeaderDetails<'a> { } impl<'a> HeaderDetails<'a> { + #[allow(clippy::int_plus_one)] pub fn render(&self, frame: &mut Frame, rect: Rect) { let bandwidth = self.bandwidth_string(); let mut elapsed_time = None; - let mut print_elapsed_time = false; - if self.state.cumulative_mode { + let print_elapsed_time = if self.state.cumulative_mode { elapsed_time = Some(self.elapsed_time_string()); - print_elapsed_time = - bandwidth.len() + elapsed_time.as_ref().unwrap().len() + 1 <= rect.width as usize; - } + bandwidth.len() + elapsed_time.as_ref().unwrap().len() + 1 <= rect.width as usize + } else { + false + }; let color = if self.paused { Color::Yellow @@ -32,22 +33,22 @@ impl<'a> HeaderDetails<'a> { }; if print_elapsed_time { - self.render_elapsed_time(frame, rect, elapsed_time.as_ref().unwrap(), &color); + self.render_elapsed_time(frame, rect, elapsed_time.as_ref().unwrap(), color); } - self.render_bandwidth(frame, rect, &bandwidth, &color); + self.render_bandwidth(frame, rect, &bandwidth, color); } fn render_bandwidth( &self, frame: &mut Frame, rect: Rect, - bandwidth: &String, - color: &Color, + bandwidth: &str, + color: Color, ) { let bandwidth_text = { [Text::styled( bandwidth, - Style::default().fg(*color).modifier(Modifier::BOLD), + Style::default().fg(color).modifier(Modifier::BOLD), )] }; @@ -76,12 +77,12 @@ impl<'a> HeaderDetails<'a> { &self, frame: &mut Frame, rect: Rect, - elapsed_time: &String, - color: &Color, + elapsed_time: &str, + color: Color, ) { let elapsed_time_text = [Text::styled( elapsed_time, - Style::default().fg(*color).modifier(Modifier::BOLD), + Style::default().fg(color).modifier(Modifier::BOLD), )]; Paragraph::new(elapsed_time_text.iter()) .alignment(Alignment::Right) -- cgit v1.2.3 From 098af1f7befaabb5f129a4bd70a070daa411ce86 Mon Sep 17 00:00:00 2001 From: Rupert Rutledge Date: Mon, 18 May 2020 21:40:36 +0100 Subject: Rename the total_bandwidth file for clarity --- src/display/components/header_details.rs | 109 ++++++++++++++++++++++++++++++ src/display/components/mod.rs | 4 +- src/display/components/total_bandwidth.rs | 109 ------------------------------ 3 files changed, 111 insertions(+), 111 deletions(-) create mode 100644 src/display/components/header_details.rs delete mode 100644 src/display/components/total_bandwidth.rs diff --git a/src/display/components/header_details.rs b/src/display/components/header_details.rs new file mode 100644 index 0000000..a3b0766 --- /dev/null +++ b/src/display/components/header_details.rs @@ -0,0 +1,109 @@ +use ::tui::backend::Backend; +use ::tui::layout::{Alignment, Rect}; +use ::tui::style::{Color, Modifier, Style}; +use ::tui::terminal::Frame; +use ::tui::widgets::{Paragraph, Text, Widget}; + +use crate::display::{DisplayBandwidth, UIState}; + +const SECONDS_IN_DAY: u64 = 86400; + +pub struct HeaderDetails<'a> { + pub state: &'a UIState, + pub elapsed_time: std::time::Duration, + pub paused: bool, +} + +impl<'a> HeaderDetails<'a> { + #[allow(clippy::int_plus_one)] + pub fn render(&self, frame: &mut Frame, rect: Rect) { + let bandwidth = self.bandwidth_string(); + let mut elapsed_time = None; + let print_elapsed_time = if self.state.cumulative_mode { + elapsed_time = Some(self.elapsed_time_string()); + bandwidth.len() + elapsed_time.as_ref().unwrap().len() + 1 <= rect.width as usize + } else { + false + }; + + let color = if self.paused { + Color::Yellow + } else { + Color::Green + }; + + if print_elapsed_time { + self.render_elapsed_time(frame, rect, elapsed_time.as_ref().unwrap(), color); + } + self.render_bandwidth(frame, rect, &bandwidth, color); + } + + fn render_bandwidth( + &self, + frame: &mut Frame, + rect: Rect, + bandwidth: &str, + color: Color, + ) { + let bandwidth_text = { + [Text::styled( + bandwidth, + Style::default().fg(color).modifier(Modifier::BOLD), + )] + }; + + Paragraph::new(bandwidth_text.iter()) + .alignment(Alignment::Left) + .render(frame, rect); + } + + fn bandwidth_string(&self) -> String { + let c_mode = self.state.cumulative_mode; + format!( + " Total Up / Down: {} / {}{}", + DisplayBandwidth { + bandwidth: self.state.total_bytes_uploaded as f64, + as_rate: !c_mode, + }, + DisplayBandwidth { + bandwidth: self.state.total_bytes_downloaded as f64, + as_rate: !c_mode, + }, + if self.paused { " [PAUSED]" } else { "" } + ) + } + + fn render_elapsed_time( + &self, + frame: &mut Frame, + rect: Rect, + elapsed_time: &str, + color: Color, + ) { + let elapsed_time_text = [Text::styled( + elapsed_time, + Style::default().fg(color).modifier(Modifier::BOLD), + )]; + Paragraph::new(elapsed_time_text.iter()) + .alignment(Alignment::Right) + .render(frame, rect); + } + + fn days_string(&self) -> String { + match self.elapsed_time.as_secs() / SECONDS_IN_DAY { + 0 => "".to_string(), + 1 => "1 day, ".to_string(), + n => format!("{} days, ", n), + } + } + + fn elapsed_time_string(&self) -> String { + format!( + "{}{:02}:{:02}:{:02} ", + self.days_string(), + (self.elapsed_time.as_secs() % SECONDS_IN_DAY) / 3600, + (self.elapsed_time.as_secs() % 3600) / 60, + self.elapsed_time.as_secs() % 60 + ) + } +} diff --git a/src/display/components/mod.rs b/src/display/components/mod.rs index c99596c..b5457f7 100644 --- a/src/display/components/mod.rs +++ b/src/display/components/mod.rs @@ -1,11 +1,11 @@ mod display_bandwidth; +mod header_details; mod help_text; mod layout; mod table; -mod total_bandwidth; pub use display_bandwidth::*; +pub use header_details::*; pub use help_text::*; pub use layout::*; pub use table::*; -pub use total_bandwidth::*; diff --git a/src/display/components/total_bandwidth.rs b/src/display/components/total_bandwidth.rs deleted file mode 100644 index a3b0766..0000000 --- a/src/display/comp