syswatch 0.1.0

Single-host, read-only system diagnostics TUI. Twelve tabs covering CPU, memory, disks, processes, GPU, power, services, network, plus a Timeline scrubber and an Insights anomaly engine. Sibling to netwatch.
use std::collections::VecDeque;

/// Bounded ring buffer for sparkline history.
#[derive(Debug, Clone)]
pub struct Ring<T> {
    cap: usize,
    inner: VecDeque<T>,
}

impl<T: Clone> Ring<T> {
    pub fn new(cap: usize) -> Self {
        Self {
            cap,
            inner: VecDeque::with_capacity(cap),
        }
    }
    pub fn push(&mut self, v: T) {
        if self.inner.len() == self.cap {
            self.inner.pop_front();
        }
        self.inner.push_back(v);
    }
    pub fn iter(&self) -> impl Iterator<Item = &T> {
        self.inner.iter()
    }
    pub fn len(&self) -> usize {
        self.inner.len()
    }
    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }
    pub fn last(&self) -> Option<&T> {
        self.inner.back()
    }
    /// Get the nth element counting back from the most recent (0 = newest).
    pub fn nth_back(&self, n: usize) -> Option<&T> {
        let len = self.inner.len();
        if n >= len {
            return None;
        }
        self.inner.get(len - 1 - n)
    }
    pub fn to_vec(&self) -> Vec<T> {
        self.inner.iter().cloned().collect()
    }
}