use std::fmt;
#[derive(Debug)]
pub enum Error {
Config(String),
Transport(String),
NotFound {
bucket: String,
key: String,
},
AccessDenied {
bucket: String,
key: String,
message: String,
},
Http {
status: u16,
code: String,
message: String,
bucket: String,
key: String,
},
Integrity(String),
Io(std::io::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Config(m) => write!(f, "configuration: {m}"),
Error::Transport(m) => write!(f, "transport: {m}"),
Error::NotFound { bucket, key } if key.is_empty() => {
write!(f, "not found: bucket {bucket}")
}
Error::NotFound { bucket, key } => write!(f, "not found: s3://{bucket}/{key}"),
Error::AccessDenied {
bucket,
key,
message,
} => {
write!(f, "access denied: s3://{bucket}/{key}")?;
if !message.is_empty() {
write!(f, " ({message})")?;
}
Ok(())
}
Error::Http {
status,
code,
message,
bucket,
key,
} => {
write!(f, "HTTP {status}")?;
if !code.is_empty() {
write!(f, " {code}")?;
}
if !message.is_empty() {
write!(f, ": {message}")?;
}
write!(f, " (s3://{bucket}/{key})")
}
Error::Integrity(m) => write!(f, "integrity: {m}"),
Error::Io(e) => write!(f, "io: {e}"),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Io(e) => Some(e),
_ => None,
}
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
}
}
pub type Result<T> = std::result::Result<T, Error>;