use std::io;
use std::path::PathBuf;
use std::process::ExitStatus;
use std::time::Duration;
#[derive(Debug, thiserror::Error)]
#[error("{action} {}: {source}", path.display())]
pub struct FileError {
pub action: &'static str,
pub path: PathBuf,
#[source]
pub source: io::Error,
}
#[derive(Debug, thiserror::Error)]
pub enum PruneError {
#[error(transparent)]
File(#[from] FileError),
#[error(transparent)]
Git(#[from] GitCallError),
}
#[derive(Debug, thiserror::Error)]
pub enum ResetError {
#[error(transparent)]
Git(#[from] GitCallError),
#[error(transparent)]
Symlinks(#[from] FileError),
}
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
pub enum HttpsAccessError {
#[error("Invalid credentials: a line break or a nul byte")]
CredentialLineBreak,
#[error("expected an http or https url")]
NotHttp,
#[error("Invalid url: its host or port could not be parsed")]
Unparsable,
#[error("expected an https credential")]
NotHttpsCredential,
}
#[derive(Debug, thiserror::Error)]
pub enum HttpsCloneError {
#[error(transparent)]
Access(#[from] HttpsAccessError),
#[error(transparent)]
Git(#[from] GitCallError),
#[error(transparent)]
Info(#[from] FileError),
}
#[derive(Debug, thiserror::Error)]
pub enum GitCallError {
#[error("git {command} could not start: {source}")]
NotStarted {
command: &'static str,
source: io::Error,
},
#[error("git {command} did not finish within {after:?}")]
TimedOut {
command: &'static str,
after: Duration,
},
#[error("git {command} exited with {status}: {stderr}")]
Refused {
command: &'static str,
status: ExitStatus,
stderr: String,
},
#[error("git {command} got an argument with an embedded null byte")]
NullByte { command: &'static str },
#[error("git {command} printed something unreadable: {reason}")]
Malformed {
command: &'static str,
reason: String,
},
}
#[derive(Debug, thiserror::Error)]
pub enum DownloadError {
#[error("writing the archive: {0}")]
Write(#[source] io::Error),
#[error(transparent)]
Fetch(#[from] FetchError),
#[error(transparent)]
Extract(#[from] ExtractError),
#[error(transparent)]
Reset(#[from] GitCallError),
#[error("pruning the working tree: {0}")]
Prune(#[from] PruneError),
#[error("placing the repository: {0}")]
Place(#[source] io::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum FetchError {
#[error("invalid url {url}: {reason}")]
InvalidUrl { url: String, reason: String },
#[error("not an http url: {0}")]
NonHttpUrl(String),
#[error("could not connect: {0}")]
Connect(#[source] reqwest::Error),
#[error("connecting timed out: {0}")]
ConnectTimeout(#[source] reqwest::Error),
#[error("no response in time: {0}")]
Timeout(#[source] reqwest::Error),
#[error("the server disconnected: {0}")]
Disconnected(#[source] reqwest::Error),
#[error("the socket failed: {source}")]
Socket {
reset: bool,
errno: Option<i32>,
source: reqwest::Error,
},
#[error("malformed response: {0}")]
Malformed(#[source] reqwest::Error),
#[error("the server answered {0}")]
Status(reqwest::StatusCode),
#[error("the body was cut: {0}")]
BodyCut(#[source] reqwest::Error),
#[error("the body did not arrive in time: {0}")]
BodyTimeout(#[source] reqwest::Error),
#[error("the request failed: {0}")]
Other(#[source] reqwest::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum ExtractError {
#[error("corrupt archive: {0}")]
Corrupt(#[source] io::Error),
#[error("truncated archive: {0}")]
Truncated(#[source] io::Error),
#[error("the archive holds no repository: {0}")]
NoRepository(String),
#[error("extracting the archive: {0}")]
Io(#[source] io::Error),
}