Skip to main content

wonfy_tools/
error.rs

1#[derive(Debug)]
2pub struct UnknownError {
3    pub name: String,
4    pub value: String,
5    pub expected: Vec<(Vec<String>, String)>,
6}
7
8impl std::fmt::Display for UnknownError {
9    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10        write!(
11            f,
12            "Unknown {} variant {}. \nexpected: ",
13            self.name, self.value
14        )?;
15
16        for (items, name) in self.expected.iter() {
17            write!(f, "\n- ")?;
18
19            for (index, item) in items.iter().enumerate() {
20                write!(
21                    f,
22                    "{}{}",
23                    item,
24                    if index == items.len() - 1 { "" } else { " | " }
25                )?;
26            }
27
28            write!(f, " => {}.", name)?;
29        }
30
31        Ok(())
32    }
33}
34
35impl std::error::Error for UnknownError {}
36
37#[derive(Debug)]
38pub struct MissingFieldError(pub String);
39
40impl std::fmt::Display for MissingFieldError {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        write!(f, "Did not set the field \"{}\" when building", self.0)
43    }
44}
45
46impl std::error::Error for MissingFieldError {}
47
48#[derive(Debug)]
49pub enum StitchError {
50    MissingField(MissingFieldError),
51    NotEnoughImages(usize),
52    InvalidWindowSize,
53    ImageTooSmall {
54        width: u32,
55        height: u32,
56        window_size: u32,
57        crop: u32,
58    },
59    ScoreOverflow {
60        window_size: u32,
61        max_width: u32,
62    },
63    NoAdapter(String),
64    Gpu(String),
65    NoCandidates,
66}
67
68impl std::fmt::Display for StitchError {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        match self {
71            Self::MissingField(err) => err.fmt(f),
72            Self::NotEnoughImages(count) => {
73                write!(f, "Need at least two images to stitch, got {count}")
74            }
75            Self::InvalidWindowSize => write!(f, "Window size must be at least 1"),
76            Self::ImageTooSmall {
77                width,
78                height,
79                window_size,
80                crop,
81            } => write!(
82                f,
83                "Image of size {width}x{height} is too small for window size {window_size} with crop {crop}"
84            ),
85            Self::ScoreOverflow {
86                window_size,
87                max_width,
88            } => write!(
89                f,
90                "Window size {window_size} with image width {max_width} would overflow the score accumulator, use a smaller window"
91            ),
92            Self::NoAdapter(details) => write!(
93                f,
94                "No compatible GPU adapter found (WebGPU/DX12/Vulkan/Metal required): {details}"
95            ),
96            Self::Gpu(details) => write!(f, "GPU error: {details}"),
97            Self::NoCandidates => write!(
98                f,
99                "No overlap candidates to score, images do not leave room for the search window"
100            ),
101        }
102    }
103}
104
105impl std::error::Error for StitchError {}
106
107impl From<MissingFieldError> for StitchError {
108    fn from(err: MissingFieldError) -> Self {
109        Self::MissingField(err)
110    }
111}
112
113macro_rules! unknown_error_expected {
114    ($($head:literal $(| $tail:literal)* => $type:literal),*) => {
115        vec![
116            $(
117                (
118                    vec![$head.to_string() $(, $tail.to_string())*],
119                    $type.to_string()
120                )
121            ),*
122        ]
123    };
124}
125
126pub(crate) use unknown_error_expected;