12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- use comm;
- use comm::Channel;
- use config::Config;
- use std::fs::File;
- use std::io::prelude::*;
- use std::io;
- use std::thread;
- struct StatFiles {
- rx: File,
- tx: File
- }
- struct Stats {
- rx: u32,
- tx: u32
- }
- pub fn netspeed(tx: &Channel, config: &Config) {
- let devices = parse_config(config);
- let mut files : Vec<StatFiles> = devices.iter()
- .flat_map(|dev| open_stats(&dev).ok())
- .collect();
- let mut prev_stats : Option<Stats> = None;
- loop {
- let stats = files
- .iter_mut()
- .flat_map(|file| read_stats(file).ok())
- .fold(Stats { rx: 0, tx: 0 }, |acc, elem| Stats {
- rx: acc.rx + elem.rx,
- tx: acc.tx + elem.tx
- });
- let output = match prev_stats {
- Some(pstats) => {
- let rx = format_bytes(stats.rx - pstats.rx);
- let tx = format_bytes(stats.tx - pstats.tx);
- format!("{}↓ {}↑", rx, tx)
- },
- None => "?".to_string()
- };
- prev_stats = Some(stats);
- comm::send(tx, "netspeed", &output);
- thread::sleep_ms(1000);
- }
- }
- fn parse_config(cfg: &Config) -> Vec<&str> {
- let val = cfg.lookup("netspeed.devices").unwrap();
- let arr = val.as_slice().unwrap();
- let arr: Vec<&str> = arr.iter().flat_map(|elem| elem.as_str()).collect();
- arr
- }
- fn format_bytes(bytes: u32) -> String {
- let kib = bytes >> 10;
- if kib > 1024 {
- format!("{:.*} M", 1, (kib as f32) / 1024.0)
- }
- else {
- format!("{} K", kib)
- }
- }
- fn open_stats(device: &str) -> Result<StatFiles, io::Error> {
- let path = format!("/sys/class/net/{}/statistics", device);
- let rx_file = try!(File::open(format!("{}/rx_bytes", path)));
- let tx_file = try!(File::open(format!("{}/tx_bytes", path)));
- Ok(StatFiles {
- rx: rx_file,
- tx: tx_file
- })
- }
- fn read_stats(files: &mut StatFiles) -> Result<Stats, io::Error> {
- Ok(Stats {
- rx: read_bytes(&mut files.rx),
- tx: read_bytes(&mut files.tx)
- })
- }
- fn read_bytes(f: &mut File) -> u32 {
- let mut s = String::new();
- assert!(f.read_to_string(&mut s).is_ok());
- let i : u32 = s.trim().parse().unwrap();
- assert!(f.seek(io::SeekFrom::Start(0)).is_ok());
- i
- }
|