summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-10-06 09:00:00 +0300
committerLars Wirzenius <liw@liw.fi>2022-10-06 09:04:41 +0300
commitbd46378ac4b20701bb9b105c1227074c2e1bf0e0 (patch)
treec3d29d9b968c6fe6e9a10de174c55f17ed724d5f
parent8246e3b8f6982410f255953aa6e210a35f88ca3f (diff)
downloadcachedir-rs-bd46378ac4b20701bb9b105c1227074c2e1bf0e0.tar.gz
refactor: use custom error type instead of anyhow
This is tidier and less magic. Sponsored-by: author
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin/cachedir.rs39
-rw-r--r--src/lib.rs22
4 files changed, 48 insertions, 25 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 22bc468..6064ce6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -101,11 +101,11 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
name = "cachedir"
version = "0.1.0"
dependencies = [
- "anyhow",
"clap 3.1.9",
"fehler",
"subplot-build",
"subplotlib",
+ "thiserror",
"walkdir",
]
@@ -1286,18 +1286,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]]
name = "thiserror"
-version = "1.0.30"
+version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
+checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.30"
+version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
+checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
dependencies = [
"proc-macro2",
"quote",
diff --git a/Cargo.toml b/Cargo.toml
index 042f8cf..3db4efd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,6 +13,6 @@ subplotlib = "0.4.1"
subplot-build = "0.4.0"
[dependencies]
-anyhow = "1.0.56"
clap = { version = "3.1.6", features = ["derive"] }
+thiserror = "1.0.37"
walkdir = "2.3.2"
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)?;
}
diff --git a/src/lib.rs b/src/lib.rs
index 5c01557..40f4f11 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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),
+}