object orientated
This commit is contained in:
parent
ade02bfe22
commit
82474262b8
2 changed files with 71 additions and 53 deletions
Binary file not shown.
88
src/main.rs
88
src/main.rs
|
@ -26,7 +26,7 @@ struct CLIArguments {
|
|||
quote: bool,
|
||||
|
||||
#[structopt(short, long, value_name="EXT",
|
||||
help="File extensions to filter for (default: jpg jpeg png webp gif heic tiff dpx exr svg)")]
|
||||
help="File extensions to filter for (default: dpx exr gif heic jpeg jpg png svg tiff webp)")]
|
||||
extensions: Vec<String>,
|
||||
|
||||
#[structopt(value_name="TARGET",
|
||||
|
@ -44,54 +44,71 @@ fn main() -> Result<(), Box<dyn std::error::Error>>{
|
|||
};
|
||||
|
||||
let valid_extensions: HashSet<&str> = if args.extensions.is_empty() {
|
||||
["jpg", "jpeg", "png", "webp", "gif", "heic", "tiff", "dpx", "exr", "svg"].into_iter().collect()
|
||||
["dpx", "exr", "gif", "heic", "jpeg", "jpg", "png", "svg", "tiff", "webp"].into_iter().collect()
|
||||
} else {
|
||||
args.extensions.iter().map(|s| s.as_str()).collect()
|
||||
};
|
||||
|
||||
let mut registry: Vec<(std::fs::Metadata,PathBuf)> = Vec::new();
|
||||
let mut registry = Registry::new(valid_extensions);
|
||||
|
||||
args.targets.into_iter().map(|target| Path::new(&target).to_path_buf() ).for_each(
|
||||
|path| {
|
||||
if path.is_file() {
|
||||
if let Ok(metadata) = std::fs::metadata(&path) { // intentionally not symlink_metadata
|
||||
register_file(&mut registry, path, metadata, &valid_extensions);
|
||||
}
|
||||
} else if path.is_dir() {
|
||||
register_dir(&mut registry, path, &valid_extensions, args.dohidden);
|
||||
}
|
||||
}
|
||||
);
|
||||
registry.populate(args.targets.into_iter().map(|target| Path::new(&target).to_path_buf() ), args.dohidden);
|
||||
|
||||
if !args.no_sort {
|
||||
registry.sort_by_key(|(meta,_)| {
|
||||
registry.sort_by_modified();
|
||||
}
|
||||
|
||||
let stdout = std::io::stdout();
|
||||
let mut stdout_buffer = std::io::BufWriter::new(stdout.lock());
|
||||
registry.write_all(&mut stdout_buffer, args.null, args.quote)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct Registry<'a> {
|
||||
registry: Vec<(std::fs::Metadata,PathBuf)>,
|
||||
valid_extensions: HashSet<&'a str>
|
||||
}
|
||||
impl<'a> Registry<'a> {
|
||||
pub fn new(valid_extensions: HashSet<&'a str>) -> Self {
|
||||
Self { registry: Vec::new(), valid_extensions }
|
||||
}
|
||||
|
||||
pub fn write_all(&self, writer: &mut impl Write, separator_null: bool, quote: bool) -> std::io::Result<()> {
|
||||
if separator_null {
|
||||
if quote { for (_,file) in &self.registry { write!(writer, "{}\0", shlex::quote(&file.to_string_lossy()))?; } }
|
||||
else { for (_,file) in &self.registry { write!(writer, "{}\0", &file.to_string_lossy() )?; } }
|
||||
} else {
|
||||
if quote { for (_,file) in &self.registry { writeln!(writer, "{}", shlex::quote(&file.to_string_lossy()))?; } }
|
||||
else { for (_,file) in &self.registry { writeln!(writer, "{}", &file.to_string_lossy() )?; } }
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn sort_by_modified(&mut self) {
|
||||
self.registry.sort_by_key(|(meta,_)| {
|
||||
meta.modified().ok().unwrap_or_else(
|
||||
|| std::time::SystemTime::UNIX_EPOCH,
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
let stdout = std::io::stdout();
|
||||
let mut stdout_buffer = std::io::BufWriter::new(stdout.lock());
|
||||
|
||||
if args.null {
|
||||
if args.quote { for (_,file) in registry { write!(stdout_buffer, "{}\0", shlex::quote(&file.to_string_lossy()))?; } }
|
||||
else { for (_,file) in registry { write!(stdout_buffer, "{}\0", &file.to_string_lossy() )?; } }
|
||||
} else {
|
||||
if args.quote { for (_,file) in registry { writeln!(stdout_buffer, "{}", shlex::quote(&file.to_string_lossy()))?; } }
|
||||
else { for (_,file) in registry { writeln!(stdout_buffer, "{}", &file.to_string_lossy() )?; } }
|
||||
pub fn populate(&mut self, source_paths: impl Iterator<Item=PathBuf>, dohidden: bool) {
|
||||
for path in source_paths {
|
||||
if path.is_file() {
|
||||
if let Ok(metadata) = std::fs::metadata(&path) { // intentionally not symlink_metadata
|
||||
self.add_file(path, metadata);
|
||||
}
|
||||
} else if path.is_dir() {
|
||||
self.add_dir(path, dohidden);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register_file(registry: &mut Vec<(std::fs::Metadata,PathBuf)>, path: PathBuf, metadata: std::fs::Metadata, valid_extensions: &HashSet<&str>) {
|
||||
fn add_file(&mut self, path: PathBuf, metadata: std::fs::Metadata) {
|
||||
if let Some(osstr_ext) = path.extension() {
|
||||
match osstr_ext.to_str() {
|
||||
Some(ext) => {
|
||||
if valid_extensions.contains(ext) {
|
||||
registry.push((metadata,path));
|
||||
}
|
||||
Some(ext) => if self.valid_extensions.contains(ext) {
|
||||
self.registry.push((metadata,path));
|
||||
},
|
||||
None => eprintln!(
|
||||
"Cannot read non-utf-8 file extension: {} on {}",
|
||||
|
@ -102,7 +119,7 @@ fn register_file(registry: &mut Vec<(std::fs::Metadata,PathBuf)>, path: PathBuf,
|
|||
}
|
||||
}
|
||||
|
||||
fn register_dir(registry: &mut Vec<(std::fs::Metadata,PathBuf)>, path: PathBuf, valid_extensions: &HashSet<&str>, dohidden: bool) {
|
||||
fn add_dir(&mut self, path: PathBuf, dohidden: bool) {
|
||||
if let Ok(entries) = std::fs::read_dir(path) {
|
||||
for path in entries.filter_map(|e| e.ok() ).map(|e| e.path() ) {
|
||||
if !dohidden && path.file_name().map(|name| name.to_string_lossy().starts_with('.')).unwrap_or(true) { // this unwraps to None if the file_name is .. or is root / (neither of which would happen in this scenario)
|
||||
|
@ -113,9 +130,10 @@ fn register_dir(registry: &mut Vec<(std::fs::Metadata,PathBuf)>, path: PathBuf,
|
|||
continue
|
||||
}
|
||||
if path.is_file() {
|
||||
register_file(registry, path, metadata, &valid_extensions)
|
||||
self.add_file(path, metadata)
|
||||
} else if path.is_dir() {
|
||||
register_dir(registry, path, &valid_extensions, dohidden);
|
||||
self.add_dir(path, dohidden);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue