Skip to content

Commit a5588fe

Browse files
committed
top: fix uptime format
1 parent 1194b3f commit a5588fe

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/top/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ windows-sys = { workspace = true, features = [
3333
[target.'cfg(target_os="linux")'.build-dependencies]
3434
pkg-config = "0.3.31"
3535

36+
[dev-dependencies]
37+
regex = { workspace = true }
38+
3639
[lib]
3740
path = "src/top.rs"
3841

src/uu/top/src/header.rs

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
use crate::picker::sysinfo;
77
use bytesize::ByteSize;
8+
use uucore::error::UResult;
89
use uucore::uptime::{
9-
get_formated_uptime, get_formatted_loadavg, get_formatted_nusers, get_formatted_time,
10+
get_formatted_loadavg, get_formatted_nusers, get_formatted_time, get_uptime, UptimeError,
1011
};
1112

1213
pub(crate) fn header(scale_summary_mem: Option<&String>) -> String {
@@ -39,12 +40,39 @@ fn format_memory(memory_b: u64, unit: u64) -> f64 {
3940
ByteSize::b(memory_b).0 as f64 / unit as f64
4041
}
4142

43+
fn format_uptime_procps(up_secs: i64) -> UResult<String> {
44+
if up_secs < 0 {
45+
Err(UptimeError::SystemUptime)?;
46+
}
47+
let up_days = up_secs / 86400;
48+
let up_hours = (up_secs - (up_days * 86400)) / 3600;
49+
let up_mins = (up_secs - (up_days * 86400) - (up_hours * 3600)) / 60;
50+
let day_str = match up_days.cmp(&1) {
51+
std::cmp::Ordering::Equal => format!("{up_days:1} day, "),
52+
std::cmp::Ordering::Greater => format!("{up_days:1} days, "),
53+
_ => String::new(),
54+
};
55+
let hour_min_str = if up_hours > 0 {
56+
format!("{up_hours:2}:{up_mins:02}")
57+
} else {
58+
format!("{up_mins:02} min")
59+
};
60+
Ok(format!("{}{}", day_str, hour_min_str))
61+
}
62+
63+
#[inline]
64+
fn get_formated_uptime_procps() -> UResult<String> {
65+
let time_str = format_uptime_procps(get_uptime(None)?)?;
66+
Ok(format!("up {}", time_str))
67+
}
68+
69+
#[inline]
4270
fn uptime() -> String {
43-
get_formated_uptime(None).unwrap_or_default()
71+
get_formated_uptime_procps().unwrap_or_default()
4472
}
4573

4674
#[cfg(target_os = "linux")]
47-
pub fn get_nusers_systemd() -> uucore::error::UResult<usize> {
75+
pub fn get_nusers_systemd() -> UResult<usize> {
4876
use std::ffi::CStr;
4977
use std::ptr;
5078
use uucore::error::USimpleError;
@@ -249,3 +277,31 @@ fn memory(scale_summary_mem: Option<&String>) -> String {
249277
unit_name = unit_name
250278
)
251279
}
280+
281+
#[cfg(test)]
282+
mod test {
283+
use super::*;
284+
285+
#[test]
286+
fn test_format_uptime() {
287+
let test_times = [
288+
1,
289+
10,
290+
60,
291+
100,
292+
200,
293+
3600,
294+
5000,
295+
3600 * 24,
296+
3600 * 24 + 60,
297+
3600 * 24 + 3600,
298+
];
299+
let re = regex::Regex::new(r"(\d+ days?,)?\s*\d+( min|:\d+)").unwrap();
300+
301+
test_times.iter().for_each(|up_secs| {
302+
let result = format_uptime_procps(*up_secs).unwrap();
303+
304+
assert!(re.is_match(&result));
305+
})
306+
}
307+
}

0 commit comments

Comments
 (0)