Skip to main content

locus_core/
error.rs

1//! Error types for the detection pipeline.
2
3use std::fmt;
4
5/// Errors that can occur during detector configuration validation.
6#[derive(Debug, Clone)]
7pub enum ConfigError {
8    /// Threshold tile size must be >= 2.
9    TileSizeTooSmall(usize),
10    /// Decimation factor must be >= 1.
11    InvalidDecimation(usize),
12    /// Upscale factor must be >= 1.
13    InvalidUpscaleFactor(usize),
14    /// Minimum fill ratio must be in [0.0, 1.0].
15    InvalidFillRatio {
16        /// The minimum fill ratio that was set.
17        min: f32,
18        /// The maximum fill ratio that was set.
19        max: f32,
20    },
21    /// Minimum edge length must be positive.
22    InvalidEdgeLength(f64),
23}
24
25impl fmt::Display for ConfigError {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        match self {
28            Self::TileSizeTooSmall(size) => {
29                write!(f, "threshold_tile_size must be >= 2, got {size}")
30            },
31            Self::InvalidDecimation(d) => {
32                write!(f, "decimation factor must be >= 1, got {d}")
33            },
34            Self::InvalidUpscaleFactor(u) => {
35                write!(f, "upscale_factor must be >= 1, got {u}")
36            },
37            Self::InvalidFillRatio { min, max } => {
38                write!(
39                    f,
40                    "fill ratio range invalid: min={min}, max={max} (must be 0.0..=1.0, min < max)"
41                )
42            },
43            Self::InvalidEdgeLength(l) => {
44                write!(f, "quad_min_edge_length must be positive, got {l}")
45            },
46        }
47    }
48}
49
50impl std::error::Error for ConfigError {}
51
52/// Errors that can occur during tag detection.
53#[derive(Debug, Clone)]
54pub enum DetectorError {
55    /// Image preprocessing (decimation or upscaling) failed.
56    Preprocessing(String),
57    /// Image view construction failed (invalid dimensions/stride).
58    InvalidImage(String),
59    /// Configuration validation failed.
60    Config(ConfigError),
61}
62
63impl fmt::Display for DetectorError {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        match self {
66            Self::Preprocessing(msg) => write!(f, "preprocessing failed: {msg}"),
67            Self::InvalidImage(msg) => write!(f, "invalid image: {msg}"),
68            Self::Config(e) => write!(f, "config error: {e}"),
69        }
70    }
71}
72
73impl std::error::Error for DetectorError {
74    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
75        match self {
76            Self::Config(e) => Some(e),
77            _ => None,
78        }
79    }
80}
81
82impl From<ConfigError> for DetectorError {
83    fn from(e: ConfigError) -> Self {
84        Self::Config(e)
85    }
86}