Last active
February 9, 2025 06:52
-
-
Save sheepla/3d82140c1a64ad19142520e4d549ac7d to your computer and use it in GitHub Desktop.
Iterate files with optional globbing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use clap::{Parser, ValueEnum}; | |
use glob::{glob, GlobError, PatternError}; | |
use std::path::PathBuf; | |
use thiserror::Error; | |
#[derive(Debug, clap::Parser)] | |
struct Args { | |
#[arg(help = "Target files path")] | |
files: Vec<String>, | |
} | |
fn main() -> Result<(), Box<AppError>> { | |
let args = Args::parse(); | |
for result in list_files(args.files.as_slice(), !args.no_glob) { | |
let path = result?; | |
println!("{}", path.to_string_lossy()); | |
} | |
Ok(()) | |
} | |
fn list_files<'a>( | |
patterns: &'a [String], | |
expand_glob: bool, | |
) -> impl Iterator<Item = Result<PathBuf, AppError>> + 'a { | |
patterns.iter().flat_map(move |pattern| { | |
let paths = if expand_glob { | |
match glob(pattern) { | |
Ok(paths) => paths, | |
Err(err) => { | |
return Box::new(std::iter::once(Err(AppError::PatternError(err)))) | |
as Box<dyn Iterator<Item = Result<PathBuf, AppError>> + 'a> | |
} | |
} | |
} else { | |
let path = PathBuf::from(pattern); | |
if path.is_file() { | |
return Box::new(std::iter::once(Ok(path))) | |
as Box<dyn Iterator<Item = Result<PathBuf, AppError>> + 'a>; | |
} else { | |
return Box::new(std::iter::empty::<Result<PathBuf, AppError>>()) | |
as Box<dyn Iterator<Item = Result<PathBuf, AppError>> + 'a>; | |
} | |
}; | |
Box::new(paths.filter_map(|p| p.ok().filter(|path| path.is_file()).map(Ok))) | |
as Box<dyn Iterator<Item = Result<PathBuf, AppError>> + 'a> | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment