use std::{fs, io};
use std::path::Path;
use std::time::Duration;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Uptime {
raw: String
}
impl Uptime {
fn path() -> &'static Path {
Path::new("/proc/uptime")
}
#[cfg(test)]
fn from_string(raw: String) -> Self {
Self {raw}
}
pub fn read() -> io::Result<Self> {
Ok(Self {
raw: fs::read_to_string(Self::path())?
})
}
pub fn all_infos<'a>(&'a self) -> impl Iterator<Item=Duration> + 'a {
self.raw.split(' ')
.filter_map(|v| v.trim().parse().ok())
.map(Duration::from_secs_f64)
}
pub fn uptime(&self) -> Option<Duration> {
self.all_infos().next()
}
pub fn idletime(&self) -> Option<Duration> {
self.all_infos().nth(1)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Hostname {
raw: String
}
impl Hostname {
fn path() -> &'static Path {
Path::new("/proc/sys/kernel/hostname")
}
#[cfg(test)]
fn from_string(raw: String) -> Self {
Self {raw}
}
pub fn read() -> io::Result<Self> {
Ok(Self {
raw: fs::read_to_string(Self::path())?
})
}
pub fn hostname(&self) -> &str {
self.raw.trim()
}
pub fn into_string(self) -> String {
self.raw
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OsRelease {
raw: String
}
impl OsRelease {
fn path() -> &'static Path {
Path::new("/proc/sys/kernel/osrelease")
}
#[cfg(test)]
fn from_string(raw: String) -> Self {
Self {raw}
}
pub fn read() -> io::Result<Self> {
Ok(Self {
raw: fs::read_to_string(Self::path())?
})
}
pub fn full_str(&self) -> &str {
self.raw.trim()
}
pub fn into_string(self) -> String {
self.raw
}
}
#[cfg(test)]
mod tests {
use super::*;
fn uptime() -> Uptime {
Uptime::from_string("220420.83 5275548.45\n".into())
}
#[test]
fn uptime_methods() {
assert_eq!(uptime().uptime().unwrap().as_secs(), 220420);
assert_eq!(uptime().idletime().unwrap().as_secs(), 5275548);
}
#[test]
fn hostname() {
let name = Hostname::from_string("test-hostname\n".into());
assert_eq!(name.hostname(), "test-hostname");
}
#[test]
fn os_release() {
let name = OsRelease::from_string("test-hostname\n".into());
assert_eq!(name.full_str(), "test-hostname");
}
}