use std::ffi::OsString;
use std::fmt;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
InvalidHexCode(String),
InvalidPaletteIndex,
InvalidExtension(OsString),
EncodingError(String),
DecodingError(String),
#[cfg(feature = "text")]
FontError(&'static str),
UnknownEncodingFormat,
IncompatibleImageData {
width: u32,
height: u32,
received: usize,
},
UnsupportedColorType,
IoError(std::io::Error),
EmptyImageError,
QuantizationOverflow {
unique_colors: usize,
palette_size: usize,
},
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::InvalidHexCode(hex_code) => write!(f, "Invalid hex code: {hex_code}"),
Self::InvalidPaletteIndex => write!(f, "Invalid palette index"),
Self::InvalidExtension(ext) => {
write!(f, "Invalid extension: {}", ext.to_string_lossy())
}
Self::EncodingError(msg) => write!(f, "Encoding error: {msg}"),
Self::DecodingError(msg) => write!(f, "Decoding error: {msg}"),
#[cfg(feature = "text")]
Self::FontError(msg) => write!(f, "Font error: {msg}"),
Self::UnknownEncodingFormat => write!(f, "Could not infer encoding format"),
Self::UnsupportedColorType => write!(
f,
"Unsupported color type. Try using the `Dynamic` pixel type instead."
),
Self::IncompatibleImageData {
width,
height,
received,
} => write!(
f,
"An image with dimensions {width}x{height} should have {} pixels, received {received} instead",
width * height,
),
Self::IoError(error) => write!(f, "IO error: {error}"),
Self::EmptyImageError => write!(f, "Tried encoding an empty image"),
Self::QuantizationOverflow {
unique_colors,
palette_size,
} => write!(
f,
"received an image with more unique colors ({unique_colors}) than the desired \
maximum ({palette_size}), use a lossy quantization algorithm (i.e. enable the \
`quantize` cargo feature) to reduce the number of colors before using this \
function.",
),
}
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::IoError(err)
}
}
#[cfg(feature = "png")]
impl From<png::EncodingError> for Error {
fn from(err: png::EncodingError) -> Self {
match err {
png::EncodingError::IoError(err) => Self::IoError(err),
png::EncodingError::Format(err) => Self::EncodingError(err.to_string()),
png::EncodingError::LimitsExceeded => {
Self::EncodingError("limits exceeded".to_string())
}
png::EncodingError::Parameter(err) => Self::EncodingError(err.to_string()),
}
}
}
#[cfg(feature = "png")]
impl From<png::DecodingError> for Error {
fn from(err: png::DecodingError) -> Self {
match err {
png::DecodingError::IoError(err) => Self::IoError(err),
png::DecodingError::Format(err) => Self::DecodingError(err.to_string()),
png::DecodingError::LimitsExceeded => {
Self::DecodingError("limits exceeded".to_string())
}
png::DecodingError::Parameter(err) => Self::DecodingError(err.to_string()),
}
}
}
#[cfg(feature = "jpeg")]
impl From<jpeg_decoder::Error> for Error {
fn from(err: jpeg_decoder::Error) -> Self {
match err {
jpeg_decoder::Error::Io(err) => Self::IoError(err),
err => Self::DecodingError(err.to_string()),
}
}
}
#[cfg(feature = "jpeg")]
impl From<jpeg_encoder::EncodingError> for Error {
fn from(err: jpeg_encoder::EncodingError) -> Self {
match err {
jpeg_encoder::EncodingError::IoError(err) => Self::IoError(err),
err => Self::EncodingError(err.to_string()),
}
}
}
#[cfg(feature = "gif")]
impl From<gif::EncodingError> for Error {
fn from(err: gif::EncodingError) -> Self {
match err {
gif::EncodingError::Io(err) => Self::IoError(err),
gif::EncodingError::Format(err) => Self::EncodingError(err.to_string()),
}
}
}
#[cfg(feature = "gif")]
impl From<gif::DecodingError> for Error {
fn from(err: gif::DecodingError) -> Self {
match err {
gif::DecodingError::Io(err) => Self::IoError(err),
gif::DecodingError::Format(err) => Self::DecodingError(err.to_string()),
}
}
}