use std::path::PathBuf;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum GlintError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Image processing error: {0}")]
Image(#[from] image::ImageError),
#[error("Configuration error: {message}")]
Config { message: String },
#[error("Sensor error: {message}")]
Sensor { message: String },
#[error("Invalid file format: {path}")]
InvalidFormat { path: PathBuf },
#[error("Missing required files: {files:?}")]
MissingFiles { files: Vec<PathBuf> },
#[error("Invalid threshold value: {value} (must be between 0.0 and 1.0)")]
InvalidThreshold { value: f64 },
#[error("Invalid bit depth: {bit_depth} (supported: 8, 16, 32)")]
InvalidBitDepth { bit_depth: u8 },
#[error("Dimension mismatch: expected {expected:?}, got {actual:?}")]
DimensionMismatch {
expected: (u32, u32),
actual: (u32, u32),
},
#[error("Band count mismatch: expected {expected}, got {actual}")]
BandCountMismatch { expected: usize, actual: usize },
#[error("Processing error: {message}")]
Processing { message: String },
#[error("Validation error: {message}")]
Validation { message: String },
#[error("Serialization error: {0}")]
Serialization(#[from] toml::ser::Error),
#[error("Deserialization error: {0}")]
Deserialization(#[from] toml::de::Error),
#[error("Pattern matching error: {pattern}")]
PatternMatch { pattern: String },
#[error("Concurrency error: {message}")]
Concurrency { message: String },
#[error("Resource exhaustion: {message}")]
ResourceExhaustion { message: String },
}
pub type Result<T> = std::result::Result<T, GlintError>;
impl GlintError {
pub fn config(message: impl Into<String>) -> Self {
Self::Config {
message: message.into(),
}
}
pub fn sensor(message: impl Into<String>) -> Self {
Self::Sensor {
message: message.into(),
}
}
pub fn processing(message: impl Into<String>) -> Self {
Self::Processing {
message: message.into(),
}
}
pub fn validation(message: impl Into<String>) -> Self {
Self::Validation {
message: message.into(),
}
}
pub fn concurrency(message: impl Into<String>) -> Self {
Self::Concurrency {
message: message.into(),
}
}
pub fn resource_exhaustion(message: impl Into<String>) -> Self {
Self::ResourceExhaustion {
message: message.into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_creation() {
let error = GlintError::config("test message");
assert!(matches!(error, GlintError::Config { .. }));
}
#[test]
fn test_error_display() {
let error = GlintError::InvalidThreshold { value: 1.5 };
let message = error.to_string();
assert!(message.contains("1.5"));
assert!(message.contains("0.0 and 1.0"));
}
}