From 3b6a350b2435826c91782b7600323ccda6213c72 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Tue, 6 May 2025 16:24:30 +0100 Subject: [PATCH] Change formatting for durations (#3198) --- libafl/src/monitors/stats/manager.rs | 4 ++-- libafl/src/monitors/tui/mod.rs | 2 +- libafl/src/monitors/tui/ui.rs | 14 ++++++------- libafl_bolts/src/lib.rs | 30 +++++++++++++++++++++++++--- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/libafl/src/monitors/stats/manager.rs b/libafl/src/monitors/stats/manager.rs index 147c2f0b19..92322d4c42 100644 --- a/libafl/src/monitors/stats/manager.rs +++ b/libafl/src/monitors/stats/manager.rs @@ -6,7 +6,7 @@ use alloc::{borrow::Cow, string::String}; use core::time::Duration; use hashbrown::HashMap; -use libafl_bolts::{ClientId, Error, current_time, format_duration_hms}; +use libafl_bolts::{ClientId, Error, current_time, format_duration}; #[cfg(feature = "std")] use serde_json::Value; @@ -171,7 +171,7 @@ impl ClientStatsManager { // Time-related data are always re-computed, since it is related with current time. let cur_time = current_time(); global_stats.run_time = cur_time - self.start_time; - global_stats.run_time_pretty = format_duration_hms(&global_stats.run_time); + global_stats.run_time_pretty = format_duration(&global_stats.run_time); global_stats.execs_per_sec = self .client_stats .iter_mut() diff --git a/libafl/src/monitors/tui/mod.rs b/libafl/src/monitors/tui/mod.rs index e4067f455b..9079b6b052 100644 --- a/libafl/src/monitors/tui/mod.rs +++ b/libafl/src/monitors/tui/mod.rs @@ -26,7 +26,7 @@ use crossterm::{ terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode}, }; use hashbrown::HashMap; -use libafl_bolts::{ClientId, Error, current_time, format_big_number, format_duration_hms}; +use libafl_bolts::{ClientId, Error, current_time, format_big_number, format_duration}; use ratatui::{Terminal, backend::CrosstermBackend}; use typed_builder::TypedBuilder; diff --git a/libafl/src/monitors/tui/ui.rs b/libafl/src/monitors/tui/ui.rs index 9e4da038f1..ef003fea57 100644 --- a/libafl/src/monitors/tui/ui.rs +++ b/libafl/src/monitors/tui/ui.rs @@ -17,7 +17,7 @@ use ratatui::{ use super::{ Duration, ItemGeometry, ProcessTiming, String, TimedStats, TuiContext, current_time, - format_duration_hms, + format_duration, }; #[derive(Default, Debug)] @@ -318,9 +318,9 @@ impl TuiUi { } let start = stats.series.front().unwrap().time; let end = stats.series.back().unwrap().time; - let min_lbl_x = format_duration_hms(&start); - let med_lbl_x = format_duration_hms(&((end - start) / 2)); - let max_lbl_x = format_duration_hms(&end); + let min_lbl_x = format_duration(&start); + let med_lbl_x = format_duration(&((end - start) / 2)); + let max_lbl_x = format_duration(&end); let x_labels = vec![ Span::styled(min_lbl_x, Style::default().add_modifier(Modifier::BOLD)), @@ -538,7 +538,7 @@ impl TuiUi { let items = vec![ Row::new(vec![ Cell::from(Span::raw("run time")), - Cell::from(Span::raw(format_duration_hms(&(current_time() - tup.0)))), + Cell::from(Span::raw(format_duration(&(current_time() - tup.0)))), ]), Row::new(vec![ Cell::from(Span::raw("exec speed")), @@ -550,11 +550,11 @@ impl TuiUi { ]), Row::new(vec![ Cell::from(Span::raw("last new entry")), - Cell::from(Span::raw(format_duration_hms(&(tup.1.last_new_entry)))), + Cell::from(Span::raw(format_duration(&(tup.1.last_new_entry)))), ]), Row::new(vec![ Cell::from(Span::raw("last solution")), - Cell::from(Span::raw(format_duration_hms(&(tup.1.last_saved_solution)))), + Cell::from(Span::raw(format_duration(&(tup.1.last_saved_solution)))), ]), ]; diff --git a/libafl_bolts/src/lib.rs b/libafl_bolts/src/lib.rs index 9b9ca7e4fd..4731829bb1 100644 --- a/libafl_bolts/src/lib.rs +++ b/libafl_bolts/src/lib.rs @@ -952,9 +952,33 @@ pub fn current_milliseconds() -> u64 { /// Format a `Duration` into a HMS string #[cfg(feature = "alloc")] #[must_use] -pub fn format_duration_hms(duration: &time::Duration) -> String { - let secs = duration.as_secs(); - format!("{}h-{}m-{}s", (secs / 60) / 60, (secs / 60) % 60, secs % 60) +pub fn format_duration(duration: &time::Duration) -> String { + const MINS_PER_HOUR: u64 = 60; + const HOURS_PER_DAY: u64 = 24; + + const SECS_PER_MINUTE: u64 = 60; + const SECS_PER_HOUR: u64 = SECS_PER_MINUTE * MINS_PER_HOUR; + const SECS_PER_DAY: u64 = SECS_PER_HOUR * HOURS_PER_DAY; + + let total_secs = duration.as_secs(); + let secs = total_secs % SECS_PER_MINUTE; + + if total_secs < SECS_PER_MINUTE { + format!("{secs}s") + } else { + let mins = (total_secs / SECS_PER_MINUTE) % MINS_PER_HOUR; + if total_secs < SECS_PER_HOUR { + format!("{mins}m-{secs}s") + } else { + let hours = (total_secs / SECS_PER_HOUR) % HOURS_PER_DAY; + if total_secs < SECS_PER_DAY { + format!("{hours}h-{mins}m-{secs}s") + } else { + let days = total_secs / SECS_PER_DAY; + format!("{days}days {hours}h-{mins}m-{secs}s") + } + } + } } /// Format a number with thousands separators