1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use std::io::{BufRead, BufReader, Read}; #[derive(Default, Debug, PartialEq)] pub struct Network { pub name: String, pub rx_bytes: u64, pub tx_bytes: u64, } impl Network { pub fn get() -> std::io::Result<Vec<Self>> { let file = std::fs::File::open("/proc/net/dev")?; Self::collect_network_stats(file) } fn collect_network_stats<R: Read>(buf: R) -> std::io::Result<Vec<Self>> { let reader = BufReader::new(buf); let networks = reader .lines() .skip(2) .map(|line| { let line = line.unwrap(); let columns: Vec<_> = line.split(":").collect(); if columns.len() < 2 { unimplemented!(); } let name = columns[0].trim_start(); let columns: Vec<_> = columns[1].split_ascii_whitespace().collect(); if columns.len() < 9 { unimplemented!(); } Network { name: name.to_owned(), rx_bytes: columns[0].parse::<u64>().unwrap(), tx_bytes: columns[8].parse::<u64>().unwrap(), } }) .filter(|network| network.name != "lo") .collect(); Ok(networks) } } #[test] fn test_collect_network_stats() { let buf = "Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed wlan0: 1188035151 850857 0 0 0 0 0 0 49774221 428282 0 0 0 0 0 0 lo: 1292817 9913 0 0 0 0 0 0 1292817 9913 0 0 0 0 0 0 eth0: 26054426 73542 0 0 0 0 0 0 12352148 58473 0 0 0 0 0 0 eth1:183651236 3482 0 0 0 0 0 0 93127469 1924 0 0 0 0 0 0".as_bytes(); let expected = vec![ Network { name: "wlan0".to_owned(), rx_bytes: 1188035151, tx_bytes: 49774221, }, Network { name: "eth0".to_owned(), rx_bytes: 26054426, tx_bytes: 12352148, }, Network { name: "eth1".to_owned(), rx_bytes: 183651236, tx_bytes: 93127469, }, ]; let r = Network::collect_network_stats(buf); assert!(r.is_ok()); assert_eq!(r.unwrap(), expected); }