clif_util/
utils.rs

1//! Utility functions.
2
3use anyhow::Context;
4use std::fs::File;
5use std::io::{self, Read};
6use std::path::{Path, PathBuf};
7use walkdir::WalkDir;
8
9/// Read an entire file into a 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.
28pub 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}