1use crate::{expect, ProcResult};
2
3use std::io::Read;
4use std::str::FromStr;
5use std::time::Duration;
6
7#[derive(Debug, Clone)]
9#[non_exhaustive]
10pub struct Uptime {
11 pub uptime: f64,
13
14 pub idle: f64,
16}
17
18impl super::FromRead for Uptime {
19 fn from_read<R: Read>(mut r: R) -> ProcResult<Self> {
20 let mut buf = Vec::with_capacity(128);
21 r.read_to_end(&mut buf)?;
22
23 let line = String::from_utf8_lossy(&buf);
24 let buf = line.trim();
25
26 let mut s = buf.split(' ');
27 let uptime = expect!(f64::from_str(expect!(s.next())));
28 let idle = expect!(f64::from_str(expect!(s.next())));
29
30 Ok(Uptime { uptime, idle })
31 }
32}
33
34impl Uptime {
35 pub fn uptime_duration(&self) -> Duration {
37 let secs = self.uptime.trunc() as u64;
38 let csecs = (self.uptime.fract() * 100.0).round() as u32;
39 let nsecs = csecs * 10_000_000;
40
41 Duration::new(secs, nsecs)
42 }
43
44 pub fn idle_duration(&self) -> Duration {
46 let secs = self.idle.trunc() as u64;
47 let csecs = (self.idle.fract() * 100.0).round() as u32;
48 let nsecs = csecs * 10_000_000;
49
50 Duration::new(secs, nsecs)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use crate::FromRead;
58 use std::io::Cursor;
59
60 #[test]
61 fn test_uptime() {
62 let reader = Cursor::new(b"2578790.61 1999230.98\n");
63 let uptime = Uptime::from_read(reader).unwrap();
64
65 assert_eq!(uptime.uptime_duration(), Duration::new(2578790, 610_000_000));
66 assert_eq!(uptime.idle_duration(), Duration::new(1999230, 980_000_000));
67 }
68}