leenfetch_core/modules/linux/info/
uptime.rs1use std::fmt::Write;
2use std::fs;
3
4use crate::modules::enums::UptimeShorthand;
5
6pub fn get_uptime(shorthand: UptimeShorthand) -> Option<String> {
7 let seconds = read_uptime_seconds()?;
8
9 Some(format_uptime(seconds, shorthand))
10}
11
12fn read_uptime_seconds() -> Option<u64> {
13 let contents = fs::read_to_string("/proc/uptime").ok()?;
14 let end = contents.find(' ')?; let raw = contents.get(0..end)?;
16 let secs = raw.parse::<f64>().ok()?;
17 Some(secs.floor() as u64)
18}
19
20fn format_uptime(seconds: u64, shorthand: UptimeShorthand) -> String {
21 let days = seconds / 86400;
22 let hours = (seconds / 3600) % 24;
23 let minutes = (seconds / 60) % 60;
24
25 let mut buf = String::with_capacity(32);
26
27 match shorthand {
28 UptimeShorthand::Full => {
29 if days > 0 {
30 let _ = write!(buf, "{} day{}, ", days, if days != 1 { "s" } else { "" });
31 }
32 if hours > 0 {
33 let _ = write!(buf, "{} hour{}, ", hours, if hours != 1 { "s" } else { "" });
34 }
35 if minutes > 0 {
36 let _ = write!(
37 buf,
38 "{} minute{}",
39 minutes,
40 if minutes != 1 { "s" } else { "" }
41 );
42 }
43 if buf.is_empty() {
44 let _ = write!(buf, "{} seconds", seconds);
45 }
46 }
47 UptimeShorthand::Tiny => {
48 if days > 0 {
49 let _ = write!(buf, "{}d", days);
50 }
51 if hours > 0 {
52 if !buf.is_empty() {
53 buf.push(' ');
54 }
55 let _ = write!(buf, "{}h", hours);
56 }
57 if minutes > 0 {
58 if !buf.is_empty() {
59 buf.push(' ');
60 }
61 let _ = write!(buf, "{}m", minutes);
62 }
63 if buf.is_empty() {
64 let _ = write!(buf, "{}s", seconds);
65 }
66 }
67 UptimeShorthand::Seconds => {
68 let _ = write!(buf, "{}s", seconds);
69 }
70 }
71
72 buf.trim_end_matches([' ', ','].as_ref()).to_string()
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn formats_full_uptime() {
81 let result = format_uptime(86_400 + 3_600 + 120, UptimeShorthand::Full);
82 assert!(
83 result.contains("1 day") && result.contains("1 hour") && result.contains("2 minutes"),
84 "unexpected format: {result}"
85 );
86 }
87
88 #[test]
89 fn formats_tiny_uptime() {
90 let result = format_uptime(86_400 * 3 + 3_600 * 2 + 120, UptimeShorthand::Tiny);
91 assert!(result.contains("3d"));
92 assert!(result.contains("2h"));
93 assert!(result.contains("2m"));
94 }
95
96 #[test]
97 fn formats_seconds_uptime() {
98 let result = format_uptime(15, UptimeShorthand::Seconds);
99 assert_eq!(result, "15s");
100 }
101}