use std::fmt;
use std::path::PathBuf;
pub enum CrapifyError {
MissingInput(PathBuf),
InputIsDirectory(PathBuf),
NoStages,
EmptyStage(usize),
UnknownStage(String),
UnsupportedFormat(String),
DecoderError(image::ImageError),
EncoderError(image::ImageError),
Io(std::io::Error),
Clap(clap::Error),
}
impl fmt::Display for CrapifyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::MissingInput(p) => {
write!(
f,
"crapify: {}: not where you said it would be.",
p.display()
)
}
Self::InputIsDirectory(p) => {
write!(
f,
"crapify: cowardly refused to crapify a directory ({}).",
p.display()
)
}
Self::NoStages => {
write!(f, "crapify: no stages given. crapify what, exactly?")
}
Self::EmptyStage(i) => {
write!(f, "crapify: empty stage at position {i}. one '+' too many.")
}
Self::UnknownStage(s) => {
write!(f, "crapify: '{s}': not a crapifier i know about.")
}
Self::UnsupportedFormat(s) => {
write!(
f,
"crapify: don't know how to encode '{s}'. try .png or .jpg."
)
}
Self::DecoderError(e) => {
write!(
f,
"crapify: that file claims to be an image but won't decode: {e}"
)
}
Self::EncoderError(e) => {
write!(
f,
"crapify: ruined the pixels, then ruined the encoder: {e}"
)
}
Self::Io(e) => write!(f, "crapify: {e}"),
Self::Clap(e) => write!(f, "{e}"),
}
}
}
impl fmt::Debug for CrapifyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl std::error::Error for CrapifyError {}
impl From<clap::Error> for CrapifyError {
fn from(e: clap::Error) -> Self {
Self::Clap(e)
}
}
impl From<std::io::Error> for CrapifyError {
fn from(e: std::io::Error) -> Self {
Self::Io(e)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn missing_input_brand_voice() {
let e = CrapifyError::MissingInput(PathBuf::from("foo.png"));
assert!(format!("{e}").starts_with("crapify: foo.png:"));
}
#[test]
fn directory_brand_voice() {
let e = CrapifyError::InputIsDirectory(PathBuf::from("/tmp"));
let s = format!("{e}");
assert!(s.starts_with("crapify: cowardly refused to crapify a directory"));
assert!(s.contains("/tmp"));
}
#[test]
fn no_stages_brand_voice() {
let e = CrapifyError::NoStages;
assert!(format!("{e}").starts_with("crapify: no stages given"));
}
#[test]
fn empty_stage_brand_voice() {
let e = CrapifyError::EmptyStage(2);
assert!(format!("{e}").contains("empty stage at position 2"));
}
#[test]
fn unknown_stage_brand_voice() {
let e = CrapifyError::UnknownStage("xerox".into());
assert!(format!("{e}").contains("'xerox': not a crapifier"));
}
#[test]
fn unsupported_format_brand_voice() {
let e = CrapifyError::UnsupportedFormat("heic".into());
assert!(format!("{e}").contains("'heic'"));
}
}