use std::{
fmt::{Debug, Display, Formatter},
path::PathBuf,
};
pub enum Error {
Ftp(ftp::FtpError),
Gcs(cloud_storage::Error),
Http(reqwest::Error),
HttpStatus(reqwest::StatusCode),
IO(std::io::Error),
Json(serde_json::Error),
Onedrive(onedrive_api::Error),
OneDriveItem(String),
OneDriveItemKind,
OneDrivePath(String),
OneDrivePrefix(String),
Other(String),
ParseChrono(String, chrono::ParseError),
ParseInt(String, std::num::ParseIntError),
ParseUrl(String, url::ParseError),
RecvAsync(async_std::channel::RecvError),
Regex(regex::Error),
S3(String),
SendAsync(String),
SendSync(String),
Sftp(ssh_transfer::Error),
Ssl(ftp::openssl::error::ErrorStack),
Tokio(tokio::task::JoinError),
Unicode(PathBuf),
}
impl From<ftp::FtpError> for Error {
fn from(error: ftp::FtpError) -> Self {
Error::Ftp(error)
}
}
impl From<cloud_storage::Error> for Error {
fn from(error: cloud_storage::Error) -> Self {
Error::Gcs(error)
}
}
impl From<reqwest::Error> for Error {
fn from(error: reqwest::Error) -> Self {
Error::Http(error)
}
}
impl From<reqwest::StatusCode> for Error {
fn from(status: reqwest::StatusCode) -> Self {
Error::HttpStatus(status)
}
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
Error::IO(error)
}
}
impl From<serde_json::Error> for Error {
fn from(error: serde_json::Error) -> Self {
Error::Json(error)
}
}
impl From<(&str, chrono::ParseError)> for Error {
fn from((string, error): (&str, chrono::ParseError)) -> Self {
Error::ParseChrono(string.to_string(), error)
}
}
impl From<(&str, std::num::ParseIntError)> for Error {
fn from((string, error): (&str, std::num::ParseIntError)) -> Self {
Error::ParseInt(string.to_string(), error)
}
}
impl From<(&str, url::ParseError)> for Error {
fn from((string, error): (&str, url::ParseError)) -> Self {
Error::ParseUrl(string.to_string(), error)
}
}
impl From<async_std::channel::RecvError> for Error {
fn from(error: async_std::channel::RecvError) -> Self {
Error::RecvAsync(error)
}
}
impl From<regex::Error> for Error {
fn from(error: regex::Error) -> Self {
Error::Regex(error)
}
}
impl From<aws_smithy_types::date_time::ConversionError> for Error {
fn from(error: aws_smithy_types::date_time::ConversionError) -> Self {
Error::S3(format!("{error:?}"))
}
}
impl<T: Debug> From<aws_sdk_s3::error::SdkError<T>> for Error {
fn from(error: aws_sdk_s3::error::SdkError<T>) -> Self {
Error::S3(format!("{error:?}"))
}
}
impl<T: Debug> From<async_std::channel::SendError<T>> for Error {
fn from(error: async_std::channel::SendError<T>) -> Self {
Error::SendAsync(format!(
"Could not send {:?} message through channel: {error:?}",
error.0
))
}
}
impl<T: Debug> From<std::sync::mpsc::SendError<T>> for Error {
fn from(error: std::sync::mpsc::SendError<T>) -> Self {
Error::SendSync(format!(
"Could not send {:?} message through channel: {error:?}",
error.0
))
}
}
impl From<ssh_transfer::Error> for Error {
fn from(error: ssh_transfer::Error) -> Self {
Error::Sftp(error)
}
}
impl From<ftp::openssl::error::ErrorStack> for Error {
fn from(error: ftp::openssl::error::ErrorStack) -> Self {
Error::Ssl(error)
}
}
impl From<tokio::task::JoinError> for Error {
fn from(error: tokio::task::JoinError) -> Self {
Error::Tokio(error)
}
}
impl From<onedrive_api::Error> for Error {
fn from(error: onedrive_api::Error) -> Self {
Self::Onedrive(error)
}
}
impl From<Error> for std::io::Error {
fn from(error: Error) -> Self {
match error {
Error::Ftp(ftp::FtpError::ConnectionError(error)) => error,
Error::IO(error) => error,
other => std::io::Error::other(other),
}
}
}
impl From<Error> for ftp::FtpError {
fn from(error: Error) -> Self {
match error {
Error::Ftp(error) => error,
Error::IO(error) => ftp::FtpError::ConnectionError(error),
other => ftp::FtpError::ConnectionError(std::io::Error::from(other)),
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Error::Ftp(error) => write!(f, "{error}"),
Error::Gcs(error) => write!(f, "{error}"),
Error::Http(error) => write!(f, "{error}"),
Error::HttpStatus(status) => write!(f, "Invalid response status: {status}"),
Error::IO(error) => write!(f, "{error}"),
Error::Json(error) => write!(f, "{error}"),
Error::Onedrive(error) => write!(f, "{error:?}"),
Error::OneDriveItem(error) => write!(f, "OneDrive item has no attribute {error}"),
Error::OneDriveItemKind => write!(f, "Invalid OneDrive item kind"),
Error::OneDrivePath(error) => write!(f, "Invalid OneDrive path: {error}"),
Error::OneDrivePrefix(error) => write!(f, "Invalid OneDrive prefix: {error}"),
Error::Other(error) => write!(f, "{error}"),
Error::ParseChrono(string, error) => {
write!(f, "Unable to parse date time from '{string}': {error}")
}
Error::ParseInt(string, error) => {
write!(f, "Unable to parse '{string}' integer: {error}")
}
Error::ParseUrl(url, error) => {
write!(f, "Unable to parse '{url}' URL: {error}")
}
Error::RecvAsync(error) => write!(f, "{error}"),
Error::Regex(error) => write!(f, "{error}"),
Error::S3(error) => write!(f, "{error}"),
Error::SendAsync(error) => write!(f, "{error}"),
Error::SendSync(error) => write!(f, "{error}"),
Error::Sftp(error) => write!(f, "{error}"),
Error::Ssl(error) => write!(f, "{error}"),
Error::Tokio(error) => write!(f, "{error}"),
Error::Unicode(error) => write! {f, "Invalid unicode encoding: {error:?}"},
}
}
}
impl Debug for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Error::Ftp(error) => write!(f, "FTP: {error:?}"),
Error::Gcs(error) => write!(f, "GCS: {error:?}"),
Error::Http(error) => write!(f, "HTTP: {error:?}"),
Error::HttpStatus(status) => write!(f, "HTTP: Invalid response status {status:?}"),
Error::IO(error) => write!(f, "IO: {error:?}"),
Error::Json(error) => write!(f, "Json: {error:?}"),
Error::Onedrive(error) => write!(f, "OneDrive: {error:?}"),
Error::OneDriveItem(error) => write!(f, "OneDrive item has no attribute {error}"),
Error::OneDriveItemKind => write!(f, "Invalid OneDrive item kind"),
Error::OneDrivePath(error) => write!(f, "Invalid OneDrive path: {error}"),
Error::OneDrivePrefix(error) => write!(f, "Invalid OneDrive prefix: {error}"),
Error::Other(error) => write!(f, "{error:?}"),
Error::ParseChrono(string, error) => {
write!(f, "Unable to parse date time from '{string}': {error:?}")
}
Error::ParseInt(string, error) => {
write!(f, "Unable to parse '{string}' integer: {error:?}")
}
Error::ParseUrl(url, error) => {
write!(f, "Unable to parse '{url}' URL: {error:?}")
}
Error::RecvAsync(error) => write!(f, "Async channel: {error:?}"),
Error::Regex(error) => write!(f, "Regex: {error:?}"),
Error::S3(error) => write!(f, "S3: {error:?}"),
Error::SendAsync(error) => write!(f, "Async channel: {error}"),
Error::SendSync(error) => write!(f, "Sync channel: {error}"),
Error::Sftp(error) => write!(f, "SFTP: {error:?}"),
Error::Ssl(error) => write!(f, "SSL: {error:?}"),
Error::Tokio(error) => write!(f, "Tokio: {error:?}"),
Error::Unicode(error) => write!(f, "Invalid unicode encoding: {error:?}"),
}
}
}
impl std::error::Error for Error {}