1use std::fmt;
4
5#[derive(Debug, Clone)]
7pub enum ConfigError {
8 TileSizeTooSmall(usize),
10 InvalidDecimation(usize),
12 InvalidUpscaleFactor(usize),
14 InvalidFillRatio {
16 min: f32,
18 max: f32,
20 },
21 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#[derive(Debug, Clone)]
54pub enum DetectorError {
55 Preprocessing(String),
57 InvalidImage(String),
59 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}