use core::{error::Error, fmt};
#[cfg(feature = "std")]
use std::io;
#[cfg(feature = "micro-qr")]
use crate::{SymbolErrorCorrection, SymbolVersion};
#[derive(Debug)]
#[non_exhaustive]
pub enum EncodeError {
DataTooLong {
required_bits: Option<usize>,
capacity_bits: usize,
},
InvalidData { mode: &'static str, byte_offset: usize },
#[cfg(feature = "micro-qr")]
TextNotRepresentable { byte_offset: usize, family: &'static str },
#[cfg(any(feature = "qr", feature = "rmqr"))]
InvalidEciAssignment(u32),
#[cfg(any(feature = "qr", feature = "rmqr"))]
InvalidApplicationIndicator,
InvalidVersionRange,
#[cfg(feature = "micro-qr")]
UnsupportedMode { mode: &'static str, family: &'static str },
#[cfg(feature = "micro-qr")]
UnsupportedErrorCorrection {
version: SymbolVersion,
error_correction: SymbolErrorCorrection,
},
InvalidMask,
#[cfg(feature = "qr")]
InvalidStructuredAppendPartCount { count: usize },
}
impl fmt::Display for EncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::DataTooLong {
required_bits,
capacity_bits,
} => {
if let Some(required_bits) = required_bits {
write!(
f,
"the encoded data needs {required_bits} bits but the selected symbols \
hold {capacity_bits} bits"
)
} else {
f.write_str("the encoded data exceeds the capacity of the selected symbols")
}
},
Self::InvalidData {
mode,
byte_offset,
} => {
write!(f, "invalid {mode} data at byte offset {byte_offset}")
},
#[cfg(feature = "micro-qr")]
Self::TextNotRepresentable {
byte_offset,
family,
} => {
write!(
f,
"the input at byte offset {byte_offset} cannot be represented by {family}"
)
},
#[cfg(any(feature = "qr", feature = "rmqr"))]
Self::InvalidEciAssignment(value) => {
write!(f, "ECI assignment {value} is outside 0..=999999")
},
#[cfg(any(feature = "qr", feature = "rmqr"))]
Self::InvalidApplicationIndicator => f.write_str("invalid FNC1 application indicator"),
Self::InvalidVersionRange => f.write_str("invalid symbol version range"),
#[cfg(feature = "micro-qr")]
Self::UnsupportedMode {
mode,
family,
} => {
write!(f, "{mode} mode is not supported by {family}")
},
#[cfg(feature = "micro-qr")]
Self::UnsupportedErrorCorrection {
version,
error_correction,
} => write!(f, "{error_correction:?} error correction is not supported by {version:?}"),
Self::InvalidMask => f.write_str("the mask number is outside the supported range"),
#[cfg(feature = "qr")]
Self::InvalidStructuredAppendPartCount {
count,
} => {
write!(f, "Structured Append requires 1..=16 parts, got {count}")
},
}
}
}
impl Error for EncodeError {}
#[derive(Debug)]
#[non_exhaustive]
pub enum RenderError {
ImageSizeTooSmall,
ImageSizeTooLarge,
#[cfg(feature = "std")]
Io(io::Error),
#[cfg(feature = "image")]
Image(image::ImageError),
}
impl fmt::Display for RenderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ImageSizeTooSmall => {
f.write_str("image size is too small to draw the whole symbol")
},
Self::ImageSizeTooLarge => f.write_str("image size is too large to generate"),
#[cfg(feature = "std")]
Self::Io(error) => fmt::Display::fmt(error, f),
#[cfg(feature = "image")]
Self::Image(error) => fmt::Display::fmt(error, f),
}
}
}
impl Error for RenderError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
#[cfg(feature = "std")]
Self::Io(error) => Some(error),
#[cfg(feature = "image")]
Self::Image(error) => Some(error),
_ => None,
}
}
}
#[cfg(feature = "std")]
impl From<io::Error> for RenderError {
#[inline]
fn from(error: io::Error) -> Self {
Self::Io(error)
}
}
#[cfg(feature = "image")]
impl From<image::ImageError> for RenderError {
#[inline]
fn from(error: image::ImageError) -> Self {
Self::Image(error)
}
}