|  | @@ -0,0 +1,80 @@
 | 
	
		
			
				|  |  | +use comm;
 | 
	
		
			
				|  |  | +use comm::Channel;
 | 
	
		
			
				|  |  | +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) {
 | 
	
		
			
				|  |  | +    let devices = [ "wlp2s0b1" ];
 | 
	
		
			
				|  |  | +    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 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
 | 
	
		
			
				|  |  | +}
 |