Skip to main content

physdes/
error.rs

1//! Error types for physdes-rs
2//!
3//! This module provides comprehensive error handling for geometric operations.
4
5use std::fmt;
6
7/// Error type for geometric operations
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum GeomError {
10    /// Invalid polygon construction
11    InvalidPolygon(String),
12
13    /// Invalid interval (lower bound > upper bound)
14    InvalidInterval { lower: i64, upper: i64 },
15
16    /// Self-intersecting polygon
17    SelfIntersectingPolygon,
18
19    /// Degenerate polygon (too few vertices)
20    DegeneratePolygon { vertex_count: usize },
21
22    /// Numerical stability issue
23    NumericalError(String),
24
25    /// Invalid point
26    InvalidPoint(String),
27}
28
29impl fmt::Display for GeomError {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            GeomError::InvalidPolygon(msg) => write!(f, "Invalid polygon: {}", msg),
33            GeomError::InvalidInterval { lower, upper } => {
34                write!(
35                    f,
36                    "Invalid interval: lower bound {} > upper bound {}",
37                    lower, upper
38                )
39            }
40            GeomError::SelfIntersectingPolygon => {
41                write!(f, "Self-intersecting polygon not allowed")
42            }
43            GeomError::DegeneratePolygon { vertex_count } => {
44                write!(
45                    f,
46                    "Degenerate polygon: insufficient vertices ({} vertices, minimum 3 required)",
47                    vertex_count
48                )
49            }
50            GeomError::NumericalError(msg) => write!(f, "Numerical error: {}", msg),
51            GeomError::InvalidPoint(msg) => write!(f, "Invalid point: {}", msg),
52        }
53    }
54}
55
56impl std::error::Error for GeomError {}
57
58/// A specialized `Result` type for geometric operations that may return a `GeomError`.
59pub type GeomResult<T> = Result<T, GeomError>;
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_error_display() {
67        let err = GeomError::InvalidPolygon("test message".to_string());
68        assert_eq!(format!("{}", err), "Invalid polygon: test message");
69
70        let err = GeomError::InvalidInterval {
71            lower: 10,
72            upper: 5,
73        };
74        assert_eq!(
75            format!("{}", err),
76            "Invalid interval: lower bound 10 > upper bound 5"
77        );
78
79        let err = GeomError::SelfIntersectingPolygon;
80        assert_eq!(format!("{}", err), "Self-intersecting polygon not allowed");
81
82        let err = GeomError::DegeneratePolygon { vertex_count: 2 };
83        assert_eq!(
84            format!("{}", err),
85            "Degenerate polygon: insufficient vertices (2 vertices, minimum 3 required)"
86        );
87    }
88
89    #[test]
90    fn test_numerical_error_display() {
91        let err = GeomError::NumericalError("division by zero".to_string());
92        assert_eq!(format!("{}", err), "Numerical error: division by zero");
93    }
94
95    #[test]
96    fn test_invalid_point_display() {
97        let err = GeomError::InvalidPoint("negative coordinates".to_string());
98        assert_eq!(format!("{}", err), "Invalid point: negative coordinates");
99    }
100}