#[derive(Debug)]
pub struct UnknownError {
pub name: String,
pub value: String,
pub expected: Vec<(Vec<String>, String)>,
}
impl std::fmt::Display for UnknownError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Unknown {} variant {}. \nexpected: ",
self.name, self.value
)?;
for (items, name) in self.expected.iter() {
write!(f, "\n- ")?;
for (index, item) in items.iter().enumerate() {
write!(
f,
"{}{}",
item,
if index == items.len() - 1 { "" } else { " | " }
)?;
}
write!(f, " => {}.", name)?;
}
Ok(())
}
}
impl std::error::Error for UnknownError {}
#[derive(Debug)]
pub struct MissingFieldError(pub String);
impl std::fmt::Display for MissingFieldError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Did not set the field \"{}\" when building", self.0)
}
}
impl std::error::Error for MissingFieldError {}
#[derive(Debug)]
pub enum StitchError {
MissingField(MissingFieldError),
NotEnoughImages(usize),
InvalidWindowSize,
ImageTooSmall {
width: u32,
height: u32,
window_size: u32,
crop: u32,
},
ScoreOverflow {
window_size: u32,
max_width: u32,
},
NoAdapter(String),
Gpu(String),
NoCandidates,
}
impl std::fmt::Display for StitchError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingField(err) => err.fmt(f),
Self::NotEnoughImages(count) => {
write!(f, "Need at least two images to stitch, got {count}")
}
Self::InvalidWindowSize => write!(f, "Window size must be at least 1"),
Self::ImageTooSmall {
width,
height,
window_size,
crop,
} => write!(
f,
"Image of size {width}x{height} is too small for window size {window_size} with crop {crop}"
),
Self::ScoreOverflow {
window_size,
max_width,
} => write!(
f,
"Window size {window_size} with image width {max_width} would overflow the score accumulator, use a smaller window"
),
Self::NoAdapter(details) => write!(
f,
"No compatible GPU adapter found (WebGPU/DX12/Vulkan/Metal required): {details}"
),
Self::Gpu(details) => write!(f, "GPU error: {details}"),
Self::NoCandidates => write!(
f,
"No overlap candidates to score, images do not leave room for the search window"
),
}
}
}
impl std::error::Error for StitchError {}
impl From<MissingFieldError> for StitchError {
fn from(err: MissingFieldError) -> Self {
Self::MissingField(err)
}
}
macro_rules! unknown_error_expected {
($($head:literal $(| $tail:literal)* => $type:literal),*) => {
vec![
$(
(
vec![$head.to_string() $(, $tail.to_string())*],
$type.to_string()
)
),*
]
};
}
pub(crate) use unknown_error_expected;