diff options
author | Lars Wirzenius <liw@liw.fi> | 2022-10-06 09:00:00 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2022-10-06 09:04:41 +0300 |
commit | bd46378ac4b20701bb9b105c1227074c2e1bf0e0 (patch) | |
tree | c3d29d9b968c6fe6e9a10de174c55f17ed724d5f /src | |
parent | 8246e3b8f6982410f255953aa6e210a35f88ca3f (diff) | |
download | cachedir-rs-bd46378ac4b20701bb9b105c1227074c2e1bf0e0.tar.gz |
refactor: use custom error type instead of anyhow
This is tidier and less magic.
Sponsored-by: author
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/cachedir.rs | 39 | ||||
-rw-r--r-- | src/lib.rs | 22 |
2 files changed, 42 insertions, 19 deletions
diff --git a/src/bin/cachedir.rs b/src/bin/cachedir.rs index 0675248..965a14d 100644 --- a/src/bin/cachedir.rs +++ b/src/bin/cachedir.rs @@ -12,9 +12,10 @@ //! $ //! ~~~ -use cachedir::{is_cachedir_tag, CACHEDIR_TAG, TAG}; +use cachedir::{is_cachedir_tag, CacheDirError, CACHEDIR_TAG, TAG}; use clap::{Parser, Subcommand}; use std::fs::{remove_file, write}; +use std::error::Error; use std::path::PathBuf; use walkdir::{DirEntry, WalkDir}; @@ -22,20 +23,26 @@ use walkdir::{DirEntry, WalkDir}; fn main() { if let Err(e) = real_main() { eprintln!("ERROR: {}", e); + + let mut e = e.source(); + while let Some(err) = e { + eprintln!("caused by: {}", err); + e = err.source(); + } + std::process::exit(1); } } /// Fallible main program. -fn real_main() -> anyhow::Result<()> { +fn real_main() -> Result<(), CacheDirError> { let args = Args::parse(); match args.cmd { - Command::Find { dirs } => walk(&dirs, find)?, - Command::Tag { dirs } => walk(&dirs, tag)?, - Command::Untag { dirs } => walk(&dirs, untag)?, - Command::IsCache { dir } => is_cache(dir)?, + Command::Find { dirs } => walk(&dirs, find), + Command::Tag { dirs } => walk(&dirs, tag), + Command::Untag { dirs } => walk(&dirs, untag), + Command::IsCache { dir } => is_cache(dir), } - Ok(()) } /// Command line arguments. @@ -59,7 +66,7 @@ enum Command { } /// Is the given directory a cache? -fn is_cache(dir: PathBuf) -> Result<(), std::io::Error> { +fn is_cache(dir: PathBuf) -> Result<(), CacheDirError> { let filename = dir.join(CACHEDIR_TAG); if !is_cachedir_tag(&filename)? { std::process::exit(1); @@ -68,7 +75,7 @@ fn is_cache(dir: PathBuf) -> Result<(), std::io::Error> { } /// Is the given directory a cache? -fn find(entry: &DirEntry) -> Result<(), std::io::Error> { +fn find(entry: &DirEntry) -> Result<(), CacheDirError> { let filename = tag_filename(entry); if is_cachedir_tag(&filename)? { println!("{}", entry.path().display()); @@ -77,31 +84,31 @@ fn find(entry: &DirEntry) -> Result<(), std::io::Error> { } /// Add a tag file to the given directory. -fn tag(entry: &DirEntry) -> Result<(), std::io::Error> { +fn tag(entry: &DirEntry) -> Result<(), CacheDirError> { let filename = tag_filename(entry); if !is_cachedir_tag(&filename)? { - write(filename, TAG)?; + write(&filename, TAG).map_err(|e| CacheDirError::Write(filename.clone(), e))?; } Ok(()) } /// Remove a tag file from the given directory. -fn untag(entry: &DirEntry) -> Result<(), std::io::Error> { +fn untag(entry: &DirEntry) -> Result<(), CacheDirError> { let filename = tag_filename(entry); if is_cachedir_tag(&filename)? { - remove_file(filename)?; + remove_file(&filename).map_err(|e| CacheDirError::Remove(filename.clone(), e))?; } Ok(()) } /// Iterate over all directories, call given function for each. -fn walk<F>(dirs: &[PathBuf], mut func: F) -> Result<(), std::io::Error> +fn walk<F>(dirs: &[PathBuf], mut func: F) -> Result<(), CacheDirError> where - F: FnMut(&DirEntry) -> Result<(), std::io::Error>, + F: FnMut(&DirEntry) -> Result<(), CacheDirError>, { for dir in dirs { for entry in WalkDir::new(dir) { - let entry = entry?; + let entry = entry.map_err(CacheDirError::WalkDir)?; if entry.metadata()?.is_dir() { func(&entry)?; } @@ -1,5 +1,5 @@ use std::fs::read; -use std::path::Path; +use std::path::{Path, PathBuf}; /// Name of tag file. pub const CACHEDIR_TAG: &str = "CACHEDIR.TAG"; @@ -8,7 +8,7 @@ pub const CACHEDIR_TAG: &str = "CACHEDIR.TAG"; pub const TAG: &str = "Signature: 8a477f597d28d172789f06886806bc55"; /// Is a given file a cache directory tag? -pub fn is_cachedir_tag(filename: &Path) -> Result<bool, std::io::Error> { +pub fn is_cachedir_tag(filename: &Path) -> Result<bool, CacheDirError> { // Is the filename OK? if let Some(basename) = filename.file_name() { if basename != CACHEDIR_TAG { @@ -23,10 +23,26 @@ pub fn is_cachedir_tag(filename: &Path) -> Result<bool, std::io::Error> { } // Does the file start with the right prefix? - let data = read(filename)?; + let data = read(filename) + .map_err(|e| CacheDirError::Read(filename.into(), e))?; if data.len() >= TAG.len() { Ok(&data[..TAG.len()] == TAG.as_bytes()) } else { Ok(false) } } + +#[derive(Debug, thiserror::Error)] +pub enum CacheDirError { + #[error("failed to read file {0}")] + Read(PathBuf, #[source] std::io::Error), + + #[error("failed to write file {0}")] + Write(PathBuf, #[source] std::io::Error), + + #[error("failed to delete file {0}")] + Remove(PathBuf, #[source] std::io::Error), + + #[error(transparent)] + WalkDir(#[from] walkdir::Error), +} |