Commit 8291318f authored by Ben Boeckel's avatar Ben Boeckel

thiserror: use `thiserror` for creating `impl Error`

parent 715408c5
Pipeline #148320 passed with stage
......@@ -20,5 +20,6 @@ lazy_static = "^1.1"
log = "~0.4"
regex = "^1.0"
tempdir = "~0.3.6"
thiserror = "^1.0.2"
chrono = "~0.4.1"
......@@ -5,13 +5,14 @@
// except according to those terms.
use std::borrow::Cow;
use std::error::Error;
use std::ffi::OsStr;
use std::fmt::{self, Display};
use std::io;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use crates::thiserror::Error;
use prepare::{GitWorkArea, WorkAreaResult};
/// The Git object id of a commit.
......@@ -22,24 +23,29 @@ pub struct CommitId(String);
///
/// This enum is `non_exhaustive`, but cannot be marked as such until it is stable. In the
/// meantime, there is a hidden variant.
#[derive(Debug)]
#[derive(Debug, Error)]
// TODO: #[non_exhaustive]
pub enum GitError {
/// Command preparation failure.
#[error("failed to construct 'git {}' command", subcommand)]
Subcommand {
/// The git subcommand which failed.
subcommand: &'static str,
/// The root cause of the failure.
#[source]
source: io::Error,
},
/// A git error occurred.
#[error("git error: '{}'", msg)]
Git {
/// Message describing what failed.
msg: Cow<'static, str>,
/// The root cause of the failure (if available).
#[source]
source: Option<io::Error>,
},
/// An invalid ref was used.
#[error("invalid git ref: '{}'", ref_)]
InvalidRef {
/// The invalid ref (or description of what was wrong).
ref_: Cow<'static, str>,
......@@ -48,6 +54,7 @@ pub enum GitError {
///
/// **DO NOT USE**
#[doc(hidden)]
#[error("unreachable...")]
_NonExhaustive,
}
......@@ -90,40 +97,6 @@ impl GitError {
}
}
impl fmt::Display for GitError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
GitError::Subcommand {
subcommand, ..
} => write!(f, "failed to construct 'git {}' command", subcommand),
GitError::Git {
msg, ..
} => write!(f, "git error: '{}'", msg),
GitError::InvalidRef {
ref_,
} => write!(f, "invalid git ref: '{}'", ref_),
nonexhaustive => unreachable!("unhandled git error: {:?}", nonexhaustive),
}
}
}
impl Error for GitError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
GitError::InvalidRef {
..
} => None,
GitError::Subcommand {
source, ..
} => Some(source),
GitError::Git {
source, ..
} => source.as_ref().map(|err| err as &dyn Error),
nonexhaustive => unreachable!("unhandled git error: {:?}", nonexhaustive),
}
}
}
pub(crate) type GitResult<T> = Result<T, GitError>;
impl CommitId {
......
......@@ -26,6 +26,7 @@ mod crates {
pub extern crate log;
pub extern crate regex;
pub extern crate tempdir;
pub extern crate thiserror;
#[cfg(test)]
pub extern crate itertools;
......
......@@ -6,7 +6,6 @@
use std::borrow::Cow;
use std::collections::hash_map::HashMap;
use std::error::Error;
use std::ffi::OsStr;
use std::fmt::{self, Debug};
use std::fs::{self, File};
......@@ -19,6 +18,7 @@ use std::process::{Command, Stdio};
use crates::chrono::{DateTime, Utc};
use crates::regex::Regex;
use crates::tempdir::TempDir;
use crates::thiserror::Error;
use git::{CommitId, GitContext, GitError, GitResult, Identity};
......@@ -39,41 +39,63 @@ pub enum SubmoduleIntent {
_NonExhaustive,
}
impl fmt::Display for SubmoduleIntent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let intent = match self {
SubmoduleIntent::CreateDirectory => "create the directory structure",
SubmoduleIntent::CreateGitFile => "create the .git file",
SubmoduleIntent::WriteGitFile => "write the .git file",
_ => unreachable!(),
};
write!(f, "{}", intent)
}
}
/// Errors which may occur when using a workarea.
///
/// This enum is `non_exhaustive`, but cannot be marked as such until it is stable. In the
/// meantime, there is a hidden variant.
#[derive(Debug)]
#[derive(Debug, Error)]
// TODO: #[non_exhaustive]
pub enum WorkAreaError {
/// Failed to create a temporary directory for the workarea.
#[error("failed to create workarea's temporary directory")]
CreateTempDirectory {
/// The cause of the failure.
#[source]
source: io::Error,
},
/// Failed to create a directory to hold the work tree.
#[error("failed to create workarea's work tree directory")]
CreateWorkTree {
/// The cause of the failure.
#[source]
source: io::Error,
},
/// Failure to set up submodules in the workarea.
#[error("failed to {} for the {} submodule", intent, submodule)]
SubmoduleSetup {
/// The action that failed.
intent: SubmoduleIntent,
/// The submodule that failed.
submodule: String,
/// The cause of the failure.
#[source]
source: io::Error,
},
/// A git operation failed.
#[error("git error: {}", source)]
Git {
/// The cause of the failure.
#[from]
source: GitError,
},
/// This is here to force `_` matching right now.
///
/// **DO NOT USE**
#[doc(hidden)]
#[error("unreachable...")]
_NonExhaustive,
}
......@@ -102,81 +124,6 @@ impl WorkAreaError {
}
}
impl fmt::Display for WorkAreaError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
WorkAreaError::CreateTempDirectory {
..
} => write!(f, "create workarea temporary directory"),
WorkAreaError::CreateWorkTree {
..
} => write!(f, "create workarea's work tree directory"),
WorkAreaError::SubmoduleSetup {
intent,
submodule,
..
} => {
match intent {
SubmoduleIntent::CreateDirectory => {
write!(
f,
"create workarea's submodule directories for {}",
submodule,
)
},
SubmoduleIntent::CreateGitFile => {
write!(
f,
"create the .git file for the workarea's {} submodule",
submodule,
)
},
SubmoduleIntent::WriteGitFile => {
write!(
f,
"write the .git file for the workarea's {} submodule",
submodule,
)
},
_ => unreachable!("unhandled intent!"),
}
},
WorkAreaError::Git {
source,
} => write!(f, "{}", source),
nonexhaustive => unreachable!("unhandled workarea error: {:?}", nonexhaustive),
}
}
}
impl Error for WorkAreaError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
WorkAreaError::CreateTempDirectory {
source,
}
| WorkAreaError::CreateWorkTree {
source,
}
| WorkAreaError::SubmoduleSetup {
source, ..
} => Some(source),
WorkAreaError::Git {
source, ..
} => Some(source),
nonexhaustive => unreachable!("unhandled workarea error: {:?}", nonexhaustive),
}
}
}
impl From<GitError> for WorkAreaError {
fn from(source: GitError) -> Self {
WorkAreaError::Git {
source,
}
}
}
pub(crate) type WorkAreaResult<T> = Result<T, WorkAreaError>;
/// Representation of merge conflict possibilities.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment