diff --git a/src/compiler.rs b/src/compiler.rs index bdbcd7a025..ed702f7c3e 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -205,7 +205,7 @@ impl Compiler { return Err( SearchError::FilesystemIo { - io_error, + source: io_error, path: directory, } .into(), @@ -214,10 +214,7 @@ impl Compiler { }; for entry in entries { - let entry = entry.map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: directory.clone(), - })?; + let entry = entry.context(search_error::FilesystemIo { path: &directory })?; if let Some(name) = entry.file_name().to_str() { for (candidate, case_sensitive) in &candidates { diff --git a/src/config.rs b/src/config.rs index 607b91a1a0..9413cb4e86 100644 --- a/src/config.rs +++ b/src/config.rs @@ -220,8 +220,7 @@ impl Config { Ok(Subcommand::Man) } else if let Some(request) = arguments.subcommand.request.as_deref() { Ok(Subcommand::Request { - request: serde_json::from_str(request) - .map_err(|source| ConfigError::RequestParse { source })?, + request: serde_json::from_str(request).context(config_error::RequestParse)?, }) } else if arguments.subcommand.show.is_some() { Ok(Subcommand::Show { diff --git a/src/datetime_format.rs b/src/datetime_format.rs index 55dbc4c6d0..a2214817ac 100644 --- a/src/datetime_format.rs +++ b/src/datetime_format.rs @@ -10,19 +10,15 @@ where { let items = StrftimeItems::new(format) .parse() - .map_err(|source| DatetimeFormatError::Parse { - format: format.into(), - source, - })?; + .context(datetime_format_error::Parse { format })?; let mut result = String::new(); datetime .format_with_items(items.iter()) .write_to(&mut result) - .map_err(|fmt::Error| DatetimeFormatError::Format { - format: format.into(), - })?; + .ok() + .context(datetime_format_error::Format { format })?; Ok(result) } diff --git a/src/datetime_format_error.rs b/src/datetime_format_error.rs index 1e7ef9ab00..467f687242 100644 --- a/src/datetime_format_error.rs +++ b/src/datetime_format_error.rs @@ -1,25 +1,13 @@ use super::*; -#[derive(Debug)] +#[derive(Debug, Snafu)] +#[snafu(visibility(pub(crate)), context(suffix(false)))] pub(crate) enum DatetimeFormatError { - Format { - format: String, - }, + #[snafu(display("failed to format time with format string `{format}`"))] + Format { format: String }, + #[snafu(display("failed to parse time format string `{format}`: {source}"))] Parse { format: String, source: chrono::ParseError, }, } - -impl Display for DatetimeFormatError { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Format { format } => { - write!(f, "failed to format time with format string `{format}`") - } - Self::Parse { source, format } => { - write!(f, "failed to parse time format string `{format}`: {source}") - } - } - } -} diff --git a/src/search.rs b/src/search.rs index ff428dadc5..116e235805 100644 --- a/src/search.rs +++ b/src/search.rs @@ -54,8 +54,7 @@ impl Search { }) } SearchConfig::FromStandardInput { working_directory } => { - let source = - io::read_to_string(io::stdin()).map_err(|io_error| SearchError::StdinIo { io_error })?; + let source = io::read_to_string(io::stdin()).context(search_error::StdinIo)?; let (justfile, tempdir) = Self::tempdir_justfile(config, &source)?; @@ -86,9 +85,7 @@ impl Search { justfile .parent() - .ok_or_else(|| SearchError::JustfileHadNoParent { - path: justfile.clone(), - })?; + .context(search_error::JustfileHadNoParent { path: &justfile })?; Self::with_justfile(config, justfile, Self::clean(config, working_directory)) } @@ -105,10 +102,7 @@ impl Search { .is_some_and(|extension| extension.eq_ignore_ascii_case("md")) { let markdown = - fs::read_to_string(&justfile).map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: justfile.clone(), - })?; + fs::read_to_string(&justfile).context(search_error::FilesystemIo { path: &justfile })?; let source = tangle(&markdown); @@ -138,14 +132,11 @@ impl Search { } else { builder.tempdir() } - .map_err(|io_error| SearchError::TempdirIo { io_error })?; + .context(search_error::TempdirIo)?; let justfile = dir::temporary_directory(&tempdir)?.join("justfile"); - fs::write(&justfile, source).map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: justfile.clone(), - })?; + fs::write(&justfile, source).context(search_error::FilesystemIo { path: &justfile })?; Ok((justfile, tempdir)) } @@ -154,10 +145,7 @@ impl Search { for (directory, filename) in Self::global_justfile_paths()? { if let Ok(read_dir) = fs::read_dir(&directory) { for entry in read_dir { - let entry = entry.map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: directory.clone(), - })?; + let entry = entry.context(search_error::FilesystemIo { path: &directory })?; let Ok(path) = entry.path().into_utf8() else { continue; @@ -179,8 +167,8 @@ impl Search { .justfile .parent() .and_then(|path| path.parent()) - .ok_or_else(|| SearchError::JustfileHadNoParent { - path: self.justfile.clone(), + .context(search_error::JustfileHadNoParent { + path: &self.justfile, })?; Self::find_in_directory(config, parent) } @@ -250,16 +238,11 @@ impl Search { for directory in directory.ancestors() { let mut candidates = BTreeSet::new(); - let entries = fs::read_dir(directory).map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: directory.to_owned(), - })?; + let entries = + fs::read_dir(directory).context(search_error::FilesystemIo { path: directory })?; for entry in entries { - let entry = entry.map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: directory.to_owned(), - })?; + let entry = entry.context(search_error::FilesystemIo { path: directory })?; let Ok(path) = entry.path().into_utf8() else { continue; @@ -303,16 +286,11 @@ impl Search { /// system directories given in `PROJECT_ROOT_CHILDREN` fn project_root(config: &Config, directory: &Utf8Path) -> SearchResult { for directory in directory.ancestors() { - let entries = fs::read_dir(directory).map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: directory.to_owned(), - })?; + let entries = + fs::read_dir(directory).context(search_error::FilesystemIo { path: directory })?; for entry in entries { - let entry = entry.map_err(|io_error| SearchError::FilesystemIo { - io_error, - path: directory.to_owned(), - })?; + let entry = entry.context(search_error::FilesystemIo { path: directory })?; for project_root_child in PROJECT_ROOT_CHILDREN.iter().copied() { if entry.file_name() == project_root_child { return Ok(directory.to_owned()); @@ -334,9 +312,7 @@ impl Search { Ok( justfile .parent() - .ok_or_else(|| SearchError::JustfileHadNoParent { - path: justfile.to_path_buf(), - })? + .context(search_error::JustfileHadNoParent { path: justfile })? .to_owned(), ) } diff --git a/src/search_error.rs b/src/search_error.rs index 925b7ebed4..aea9fde124 100644 --- a/src/search_error.rs +++ b/src/search_error.rs @@ -3,9 +3,9 @@ use super::*; #[derive(Debug, Snafu)] #[snafu(visibility(pub(crate)), context(suffix(false)))] pub(crate) enum SearchError { - #[snafu(display("I/O error at `{path}`: {io_error}"))] + #[snafu(display("I/O error at `{path}`: {source}"))] FilesystemIo { - io_error: io::Error, + source: io::Error, path: Utf8PathBuf, }, #[snafu(display("cannot initialize global justfile"))] @@ -30,10 +30,10 @@ pub(crate) enum SearchError { NotFound, #[snafu(transparent)] Path { source: PathError }, - #[snafu(display("error reading from standard input: {io_error}"))] - StdinIo { io_error: io::Error }, - #[snafu(display("I/O error creating temporary directory: {io_error}"))] - TempdirIo { io_error: io::Error }, + #[snafu(display("error reading from standard input: {source}"))] + StdinIo { source: io::Error }, + #[snafu(display("I/O error creating temporary directory: {source}"))] + TempdirIo { source: io::Error }, } #[cfg(test)]