Skip to content

Instantly share code, notes, and snippets.

@rkuris
Created January 4, 2023 00:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkuris/7028f2551ed334f9d90594cc88dbf058 to your computer and use it in GitHub Desktop.
Save rkuris/7028f2551ed334f9d90594cc88dbf058 to your computer and use it in GitHub Desktop.
More idiomatic rust
use anyhow::{Context, Error, Result};
use itertools::Itertools;
use regex::Regex;
use std::{
fs::File,
io::{BufRead, BufReader},
};
fn main() -> Result<()> {
let file_path = std::env::args()
.nth(1)
.expect("expected pathname argument");
let file = File::open(&file_path)
.context(format!("Unable to open {}", file_path))
.map_err(Error::msg)?;
println!("slowest 10 files:");
for (file, speed) in slowest(10, BufReader::new(file))? {
println!("{file} {speed}s");
}
Ok(())
}
fn slowest<R: BufRead>(n: usize, iterator: R) -> Result<Vec<(String, f64)>> {
let re = Regex::new(r"took ([\d.]+) s")?;
let mut times: Vec<(String, f64)> = BufReader::new(iterator)
.lines()
.map(|line| line.expect("error reading file"))
.filter(|line| !line.is_empty())
.chunks(2)
.into_iter()
.map(|mut chunk| {
let filename = chunk
.next()
.expect("couldn't find the first line of a pair of lines");
let statline = chunk
.next()
.expect("couldn't find the second line of a pair of lines");
let caps = re
.captures(&statline)
.expect("couldn't take a regex of the stat line");
(
filename,
caps.get(1)
.map_or("", |m| m.as_str())
.parse::<f64>()
.expect("couldn't parse a f64"),
)
})
.collect();
times.sort_by(|(_, speeda), (_, speedb)| speedb.partial_cmp(speeda).unwrap());
Ok(times.into_iter().take(n).collect())
}
#[cfg(test)]
mod test {
use std::io::Cursor;
use super::slowest; // super slowest ROFL
#[test]
fn test_longest() {
let lines = "file1\ntook 1 s\nfile2\ntook 2 s";
assert_eq!(
slowest(1, Cursor::new(lines)).unwrap(),
vec![("file2".to_owned(), 2.0)]
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment