use std::fs::File; use std::io::{Read, Write}; use std::ops::Sub; use std::thread::sleep; use std::time::{Duration, Instant}; #[derive(Copy, Clone, Debug)] struct ByteState { pub recv: u64, pub send: u64, } impl Sub for ByteState { type Output = ByteState; fn sub(self, rhs: Self) -> Self::Output { let mut result_byte_state = ByteState { recv: 0, send: 0 }; if self.recv >= rhs.recv { result_byte_state.recv = self.recv - rhs.recv; } if self.send >= rhs.send { result_byte_state.send = self.send - rhs.send; } result_byte_state } } fn read_proc_net_dev(net_device: &str) -> Result { let mut byte_state = ByteState { recv: 0, send: 0 }; let mut file_string = String::new(); { let mut file = File::open("/proc/net/dev") .map_err(|_| String::from("Failed to open \"/proc/net/dev\""))?; file.read_to_string(&mut file_string) .map_err(|_| String::from("Failed to read from \"/proc/net/dev\""))?; } for line in file_string.lines() { if line.trim().starts_with(net_device) { let mut count = 0u32; for word in line.split(' ') { if count == 1 { byte_state.recv = u64::from_str_radix(word, 10).map_err(|_| { String::from("Failed to parse recv bytes from \"/proc/net/dev\"") })?; } else if count == 9 { byte_state.send = u64::from_str_radix(word, 10).map_err(|_| { String::from("Failed to parse send bytes from \"/proc/net/dev\"") })?; return Ok(byte_state); } count += 1; } return Err(String::from( "Failed to parse from \"/proc/net/dev\", too few words?", )); } } Err(String::from( "Failed to parse from \"/proc/net/dev\", missing device?", )) } fn write_compare_state( net_device: &str, send_filename: &str, recv_filename: &str, ) -> Result { let mut prev_byte_state = ByteState { send: 0, recv: 0 }; { let mut temp_string: String = String::new(); let send_file_open_result = File::open(send_filename); if let Ok(mut send_file) = send_file_open_result { let read_result = send_file.read_to_string(&mut temp_string); if read_result.is_ok() { let int_parse_result = u64::from_str_radix(temp_string.trim(), 10); if let Ok(i) = int_parse_result { prev_byte_state.send = i; } } } } { let mut temp_string: String = String::new(); let recv_file_open_result = File::open(recv_filename); if let Ok(mut recv_file) = recv_file_open_result { let read_result = recv_file.read_to_string(&mut temp_string); if read_result.is_ok() { let int_parse_result = u64::from_str_radix(temp_string.trim(), 10); if let Ok(i) = int_parse_result { prev_byte_state.recv = i; } } } } let byte_state = read_proc_net_dev(net_device)?; { let mut send_file = File::create(send_filename) .map_err(|_| format!("Failed to create \"{}\"", send_filename))?; send_file .write_all(byte_state.send.to_string().as_bytes()) .map_err(|_| format!("Failed to write into \"{}\"", send_filename))?; } { let mut recv_file = File::create(recv_filename) .map_err(|_| format!("Failed to create \"{}\"", recv_filename))?; recv_file .write_all(byte_state.recv.to_string().as_bytes()) .map_err(|_| format!("Failed to write into \"{}\"", recv_filename))?; } Ok(byte_state - prev_byte_state) } fn timer_execute(func: F, sleep_seconds: u64) -> Result<(), String> where F: std::ops::Fn() -> Result<(), String>, { let mut instant = Instant::now() - Duration::from_secs(sleep_seconds); let diff_duration = Duration::from_secs(sleep_seconds * 2); let mut duration: Duration; loop { func()?; let newer_instant = Instant::now(); duration = diff_duration - (newer_instant - instant); instant = newer_instant; sleep(duration); } } fn main() { println!("Hello, world!"); }