1use oxigdal_core::error::OxiGdalError;
4use thiserror::Error;
5
6pub type Result<T> = core::result::Result<T, VrtError>;
8
9#[derive(Debug, Error)]
11pub enum VrtError {
12 #[error("XML parsing error: {message}")]
14 XmlParse {
15 message: String,
17 },
18
19 #[error("Invalid VRT structure: {message}")]
21 InvalidStructure {
22 message: String,
24 },
25
26 #[error("Source file not found: {path}")]
28 SourceNotFound {
29 path: String,
31 },
32
33 #[error("Source file error '{path}': {message}")]
35 SourceError {
36 path: String,
38 message: String,
40 },
41
42 #[error("Invalid source configuration: {message}")]
44 InvalidSource {
45 message: String,
47 },
48
49 #[error("Invalid band configuration: {message}")]
51 InvalidBand {
52 message: String,
54 },
55
56 #[error("Band {band} out of range (0-{max})")]
58 BandOutOfRange {
59 band: usize,
61 max: usize,
63 },
64
65 #[error("Invalid extent: {message}")]
67 InvalidExtent {
68 message: String,
70 },
71
72 #[error("Invalid window: {message}")]
74 InvalidWindow {
75 message: String,
77 },
78
79 #[error("Invalid pixel function: {function}")]
81 InvalidPixelFunction {
82 function: String,
84 },
85
86 #[error("Missing required attribute: {attribute}")]
88 MissingAttribute {
89 attribute: String,
91 },
92
93 #[error("Path resolution error for '{path}': {message}")]
95 PathResolution {
96 path: String,
98 message: String,
100 },
101
102 #[error("Cache error: {message}")]
104 CacheError {
105 message: String,
107 },
108
109 #[error("Incompatible sources: {message}")]
111 IncompatibleSources {
112 message: String,
114 },
115
116 #[error("I/O error: {0}")]
118 Io(#[from] std::io::Error),
119
120 #[error("OxiGDAL error: {0}")]
122 Core(#[from] OxiGdalError),
123}
124
125impl VrtError {
126 pub fn xml_parse<S: Into<String>>(message: S) -> Self {
128 Self::XmlParse {
129 message: message.into(),
130 }
131 }
132
133 pub fn invalid_structure<S: Into<String>>(message: S) -> Self {
135 Self::InvalidStructure {
136 message: message.into(),
137 }
138 }
139
140 pub fn source_not_found<S: Into<String>>(path: S) -> Self {
142 Self::SourceNotFound { path: path.into() }
143 }
144
145 pub fn source_error<S: Into<String>, M: Into<String>>(path: S, message: M) -> Self {
147 Self::SourceError {
148 path: path.into(),
149 message: message.into(),
150 }
151 }
152
153 pub fn invalid_source<S: Into<String>>(message: S) -> Self {
155 Self::InvalidSource {
156 message: message.into(),
157 }
158 }
159
160 pub fn invalid_band<S: Into<String>>(message: S) -> Self {
162 Self::InvalidBand {
163 message: message.into(),
164 }
165 }
166
167 pub fn band_out_of_range(band: usize, max: usize) -> Self {
169 Self::BandOutOfRange { band, max }
170 }
171
172 pub fn invalid_extent<S: Into<String>>(message: S) -> Self {
174 Self::InvalidExtent {
175 message: message.into(),
176 }
177 }
178
179 pub fn invalid_window<S: Into<String>>(message: S) -> Self {
181 Self::InvalidWindow {
182 message: message.into(),
183 }
184 }
185
186 pub fn missing_attribute<S: Into<String>>(attribute: S) -> Self {
188 Self::MissingAttribute {
189 attribute: attribute.into(),
190 }
191 }
192
193 pub fn path_resolution<S: Into<String>, M: Into<String>>(path: S, message: M) -> Self {
195 Self::PathResolution {
196 path: path.into(),
197 message: message.into(),
198 }
199 }
200
201 pub fn cache_error<S: Into<String>>(message: S) -> Self {
203 Self::CacheError {
204 message: message.into(),
205 }
206 }
207
208 pub fn incompatible_sources<S: Into<String>>(message: S) -> Self {
210 Self::IncompatibleSources {
211 message: message.into(),
212 }
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[test]
221 fn test_error_creation() {
222 let err = VrtError::xml_parse("test error");
223 assert!(matches!(err, VrtError::XmlParse { .. }));
224
225 let err = VrtError::source_not_found("/path/to/file.tif");
226 assert!(matches!(err, VrtError::SourceNotFound { .. }));
227
228 let err = VrtError::band_out_of_range(5, 3);
229 assert!(matches!(err, VrtError::BandOutOfRange { band: 5, max: 3 }));
230 }
231
232 #[test]
233 fn test_error_display() {
234 let err = VrtError::xml_parse("invalid XML");
235 assert_eq!(err.to_string(), "XML parsing error: invalid XML");
236
237 let err = VrtError::source_not_found("/test.tif");
238 assert_eq!(err.to_string(), "Source file not found: /test.tif");
239
240 let err = VrtError::band_out_of_range(5, 3);
241 assert_eq!(err.to_string(), "Band 5 out of range (0-3)");
242 }
243}