use sysinfo::System;
use crate::payload::{Body, EntriesData, Payload, TextData};
use crate::render::Shape;
use crate::samples;
use super::super::{FetchContext, RealtimeFetcher, Safety};
use super::{entry, format_load, load_line, payload};
pub struct SystemMonitorLoad;
impl RealtimeFetcher for SystemMonitorLoad {
fn name(&self) -> &str {
"system_monitor_load"
}
fn safety(&self) -> Safety {
Safety::Safe
}
fn description(&self) -> &'static str {
"Unix 1 / 5 / 15-minute load averages. `Text` joins the three values on one line; `Entries` splits them into separate rows. Reads as `\"n/a (windows)\"` on Windows, which has no equivalent counter."
}
fn shapes(&self) -> &[Shape] {
&[Shape::Text, Shape::Entries]
}
fn sample_body(&self, shape: Shape) -> Option<Body> {
Some(match shape {
Shape::Text => samples::text("0.42 0.38 0.31"),
Shape::Entries => {
samples::entries(&[("1min", "0.42"), ("5min", "0.38"), ("15min", "0.31")])
}
_ => return None,
})
}
fn compute(&self, ctx: &FetchContext) -> Payload {
let la = System::load_average();
match ctx.shape.unwrap_or(Shape::Text) {
Shape::Entries => payload(Body::Entries(EntriesData {
items: vec![
entry("1min", &format_load(la.one)),
entry("5min", &format_load(la.five)),
entry("15min", &format_load(la.fifteen)),
],
})),
_ => payload(Body::Text(TextData {
value: load_line(la.one, la.five, la.fifteen),
})),
}
}
}
#[cfg(test)]
mod tests {
use super::super::test_helpers::ctx_with_shape;
use super::*;
#[test]
fn load_average_defaults_to_text() {
let p = SystemMonitorLoad.compute(&ctx_with_shape(None));
assert!(matches!(p.body, Body::Text(_)));
}
#[test]
fn load_average_entries_shape_has_three_windows() {
let p = SystemMonitorLoad.compute(&ctx_with_shape(Some(Shape::Entries)));
assert!(matches!(p.body, Body::Entries(_)));
if let Body::Entries(e) = p.body {
let keys: Vec<_> = e.items.iter().map(|i| i.key.as_str()).collect();
assert_eq!(keys, ["1min", "5min", "15min"]);
}
}
}