Mercurial > hg-stable
diff rust/hg-core/src/errors.rs @ 46638:1f55cd5b292f
rust: Add a log file rotation utility
This is ported to Rust from `mercurial/loggingutil.py`.
The "builder" pattern is used to make it visible at call sites what the two
numeric parameters mean. In Python they might simply by keyword arguments.
Differential Revision: https://phab.mercurial-scm.org/D10010
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 11 Feb 2021 15:51:11 +0100 |
parents | bc08c2331f99 |
children | 3d692e724d06 |
line wrap: on
line diff
--- a/rust/hg-core/src/errors.rs Tue Feb 16 15:22:20 2021 +0100 +++ b/rust/hg-core/src/errors.rs Thu Feb 11 15:51:11 2021 +0100 @@ -41,11 +41,15 @@ } /// Details about where an I/O error happened -#[derive(Debug, derive_more::From)] +#[derive(Debug)] pub enum IoErrorContext { - /// A filesystem operation for the given file - #[from] - File(std::path::PathBuf), + ReadingFile(std::path::PathBuf), + WritingFile(std::path::PathBuf), + RemovingFile(std::path::PathBuf), + RenamingFile { + from: std::path::PathBuf, + to: std::path::PathBuf, + }, /// `std::env::current_dir` CurrentDir, /// `std::env::current_exe` @@ -109,28 +113,55 @@ impl fmt::Display for IoErrorContext { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - IoErrorContext::File(path) => path.display().fmt(f), - IoErrorContext::CurrentDir => f.write_str("current directory"), - IoErrorContext::CurrentExe => f.write_str("current executable"), + IoErrorContext::ReadingFile(path) => { + write!(f, "when reading {}", path.display()) + } + IoErrorContext::WritingFile(path) => { + write!(f, "when writing {}", path.display()) + } + IoErrorContext::RemovingFile(path) => { + write!(f, "when removing {}", path.display()) + } + IoErrorContext::RenamingFile { from, to } => write!( + f, + "when renaming {} to {}", + from.display(), + to.display() + ), + IoErrorContext::CurrentDir => write!(f, "current directory"), + IoErrorContext::CurrentExe => write!(f, "current executable"), } } } pub trait IoResultExt<T> { - /// Annotate a possible I/O error as related to a file at the given path. + /// Annotate a possible I/O error as related to a reading a file at the + /// given path. /// - /// This allows printing something like “File not found: example.txt” - /// instead of just “File not found”. + /// This allows printing something like “File not found when reading + /// example.txt” instead of just “File not found”. /// /// Converts a `Result` with `std::io::Error` into one with `HgError`. - fn for_file(self, path: &std::path::Path) -> Result<T, HgError>; + fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError>; + + fn with_context( + self, + context: impl FnOnce() -> IoErrorContext, + ) -> Result<T, HgError>; } impl<T> IoResultExt<T> for std::io::Result<T> { - fn for_file(self, path: &std::path::Path) -> Result<T, HgError> { + fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError> { + self.with_context(|| IoErrorContext::ReadingFile(path.to_owned())) + } + + fn with_context( + self, + context: impl FnOnce() -> IoErrorContext, + ) -> Result<T, HgError> { self.map_err(|error| HgError::IoError { error, - context: IoErrorContext::File(path.to_owned()), + context: context(), }) } }