1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, IffError>;
7
8#[derive(Error, Debug)]
10pub enum IffError {
11 #[error("Invalid magic number: expected 0x{expected:08X}, got 0x{got:08X}")]
13 InvalidMagic { expected: u32, got: u32 },
14
15 #[error("Unsupported version: {0}")]
17 UnsupportedVersion(u32),
18
19 #[error("Image dimension {dimension} exceeds maximum {max}")]
21 DimensionTooLarge { dimension: u32, max: u32 },
22
23 #[error("Invalid wavelet coefficient at ({x}, {y}, {level})")]
25 InvalidWaveletCoefficient { x: usize, y: usize, level: usize },
26
27 #[error("Invalid region: position ({x}, {y}), size ({w}, {h})")]
29 InvalidRegion {
30 x: u16,
31 y: u16,
32 w: u16,
33 h: u16,
34 },
35
36 #[error("Invalid vortex at position ({x}, {y})")]
38 InvalidVortex { x: u16, y: u16 },
39
40 #[error("Fixed-point overflow in operation: {operation}")]
42 FixedPointOverflow { operation: String },
43
44 #[error("Insufficient data: expected {expected} bytes, got {got}")]
46 InsufficientData { expected: usize, got: usize },
47
48 #[error("Corrupted bitstream at offset {offset}: {reason}")]
50 CorruptedBitstream { offset: usize, reason: String },
51
52 #[error("IO error: {0}")]
54 Io(#[from] std::io::Error),
55
56 #[error("Serialization error: {0}")]
58 Serialization(String),
59
60 #[cfg(feature = "gpu")]
62 #[error("GPU error: {0}")]
63 Gpu(String),
64
65 #[cfg(feature = "encoder")]
67 #[error("Encoding error: {0}")]
68 Encoding(String),
69
70 #[cfg(feature = "decoder")]
72 #[error("Decoding error: {0}")]
73 Decoding(String),
74
75 #[error("{0}")]
77 Other(String),
78}
79
80impl From<bincode::Error> for IffError {
81 fn from(err: bincode::Error) -> Self {
82 IffError::Serialization(err.to_string())
83 }
84}
85
86impl From<rmp_serde::encode::Error> for IffError {
87 fn from(err: rmp_serde::encode::Error) -> Self {
88 IffError::Serialization(err.to_string())
89 }
90}
91
92impl From<rmp_serde::decode::Error> for IffError {
93 fn from(err: rmp_serde::decode::Error) -> Self {
94 IffError::Serialization(err.to_string())
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_error_display() {
104 let err = IffError::InvalidMagic {
105 expected: 0x50504649,
106 got: 0x12345678,
107 };
108 assert!(err.to_string().contains("0x50504649"));
109 assert!(err.to_string().contains("0x12345678"));
110 }
111
112 #[test]
113 fn test_dimension_error() {
114 let err = IffError::DimensionTooLarge {
115 dimension: 100000,
116 max: 65536,
117 };
118 assert!(err.to_string().contains("100000"));
119 assert!(err.to_string().contains("65536"));
120 }
121}