linescroll 0.2.0

report the number of lines input per time ranges and present rate as statistics and graph
Documentation
use std::sync::{Arc, Mutex};

#[derive(Debug, Clone)]
pub struct FileWatch {
    pub count: Arc<Mutex<u64>>,
    pub minute: Vec<u64>,
    pub five_minute: Vec<u64>,
    pub fifteen_minute: Vec<u64>,
    pub name: String,
}

#[derive(Clone)]
pub struct Settings {
    pub combine: bool,
    pub speedonly: bool,
    pub print_every: usize,
    pub limit: usize,
    pub filenames: bool,
    pub noclear: bool,
    pub nofollow: bool,
    pub raw: bool,
    pub exit: bool,
    pub axislimit: bool,
}

pub fn average_set(set: &[u64]) -> u64 {
    let mut avg: u64 = 0;
    for x in set.iter() {
        avg += x;
    }
    avg / set.len() as u64
}

pub fn graph(minute: &[u64], axislimit: bool) -> String {
    let height: u64 = 10;
    let mut max_delta: u64 = 0;
    let mut s = String::new();

    if minute.len() < 2 {
        for _ in 1..10 {
            s.push('\n');
        }
        return s;
    }

    // get the limit for the graph
    for val in minute.iter().skip(1) {
        if val > &max_delta {
            max_delta = *val;
        }
    }

    for line in 1..height {
        s.push_str(&format!("{:10}", ""));
        for hist in minute.iter().skip(1) {
            s.push_str(
                if *hist as f64 > (max_delta as f64 / height as f64) * (height as f64 - line as f64)
                {
                    "#"
                } else {
                    " "
                },
            );
        }
        if line == 1 && axislimit {
            for _ in minute.len()..=60 {
                s.push(' ');
            }
            s.push_str(&format!(" {}", max_delta));
        }
        if line == height - 1 && axislimit {
            for _ in minute.len()..=60 {
                s.push(' ');
            }
            s.push_str(" 0");
        }

        s.push('\n');
    }
    s
}

pub fn filename_print(settings: &Settings, item: &FileWatch) -> String {
    if settings.filenames {
        format!("{}\n", item.name)
    } else {
        "".to_string()
    }
}

pub fn trim_item(item: &mut FileWatch, size: usize) {
    while item.minute.len() > size + 1 {
        item.minute.remove(0);
    }

    while item.five_minute.len() > (size + 1) * 5 {
        item.five_minute.remove(0);
    }

    while item.fifteen_minute.len() > (size + 1) * 15 {
        item.fifteen_minute.remove(0);
    }
}

pub fn should_clear(settings: &Settings) -> bool {
    !settings.noclear
}

pub fn should_print(settings: &Settings, iterations: usize) -> bool {
    if settings.print_every != 1 && (iterations % settings.print_every != 0 || iterations == 0) {
        return false;
    }
    true
}