1 //! Utility functions. 2 3 use anyhow::Context; 4 use std::fs::File; 5 use std::io::{self, Read}; 6 use std::path::{Path, PathBuf}; 7 use walkdir::WalkDir; 8 9 /// Read an entire file into a string. read_to_string<P: AsRef<Path>>(path: P) -> anyhow::Result<String>10pub fn read_to_string<P: AsRef<Path>>(path: P) -> anyhow::Result<String> { 11 let mut buffer = String::new(); 12 let path = path.as_ref(); 13 if path == Path::new("-") { 14 let stdin = io::stdin(); 15 let mut stdin = stdin.lock(); 16 stdin 17 .read_to_string(&mut buffer) 18 .context("failed to read stdin to string")?; 19 } else { 20 let mut file = File::open(path)?; 21 file.read_to_string(&mut buffer) 22 .with_context(|| format!("failed to read {} to string", path.display()))?; 23 } 24 Ok(buffer) 25 } 26 27 /// Iterate over all of the files passed as arguments, recursively iterating through directories. iterate_files<'a>(files: &'a [PathBuf]) -> impl Iterator<Item = PathBuf> + 'a28pub fn iterate_files<'a>(files: &'a [PathBuf]) -> impl Iterator<Item = PathBuf> + 'a { 29 files 30 .iter() 31 .flat_map(WalkDir::new) 32 .filter(|f| match f { 33 Ok(d) => { 34 // Filter out hidden files (starting with .). 35 !d.file_name().to_str().map_or(false, |s| s.starts_with('.')) 36 // Filter out directories. 37 && !d.file_type().is_dir() 38 } 39 Err(e) => { 40 println!("Unable to read file: {e}"); 41 false 42 } 43 }) 44 .map(|f| { 45 f.expect("this should not happen: we have already filtered out the errors") 46 .into_path() 47 }) 48 } 49