Skip to main content

use_geometry/
error.rs

1use core::fmt;
2use std::error::Error;
3
4/// Errors returned by validated geometry constructors.
5#[derive(Debug, Clone, PartialEq)]
6pub enum GeometryError {
7    /// A geometry component must be finite.
8    ///
9    /// The type name, component name, and invalid value are included for
10    /// diagnostics.
11    NonFiniteComponent {
12        /// The type that rejected the invalid component.
13        type_name: &'static str,
14        /// The component that rejected the invalid value.
15        component: &'static str,
16        /// The invalid component value.
17        value: f64,
18    },
19    /// A circle radius cannot be negative.
20    ///
21    /// The invalid radius value is included for diagnostics.
22    NegativeRadius(f64),
23    /// A circle radius must be finite.
24    ///
25    /// The invalid radius value is included for diagnostics.
26    NonFiniteRadius(f64),
27    /// A tolerance must be finite.
28    ///
29    /// The invalid tolerance value is included for diagnostics.
30    NonFiniteTolerance(f64),
31    /// A tolerance cannot be negative.
32    ///
33    /// The invalid tolerance value is included for diagnostics.
34    NegativeTolerance(f64),
35    /// Distinct points were required but identical points were supplied.
36    IdenticalPoints,
37    /// A non-zero direction vector was required.
38    ZeroDirectionVector,
39    /// An axis-aligned bounding box corner ordering was invalid.
40    InvalidBounds {
41        /// The minimum x coordinate.
42        min_x: f64,
43        /// The minimum y coordinate.
44        min_y: f64,
45        /// The maximum x coordinate.
46        max_x: f64,
47        /// The maximum y coordinate.
48        max_y: f64,
49    },
50}
51
52impl GeometryError {
53    pub(crate) const fn non_finite_component(
54        type_name: &'static str,
55        component: &'static str,
56        value: f64,
57    ) -> Self {
58        Self::NonFiniteComponent {
59            type_name,
60            component,
61            value,
62        }
63    }
64
65    pub(crate) const fn validate_tolerance(tolerance: f64) -> Result<f64, Self> {
66        if !tolerance.is_finite() {
67            return Err(Self::NonFiniteTolerance(tolerance));
68        }
69
70        if tolerance < 0.0 {
71            return Err(Self::NegativeTolerance(tolerance));
72        }
73
74        Ok(tolerance)
75    }
76}
77
78impl fmt::Display for GeometryError {
79    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
80        match self {
81            Self::NonFiniteComponent {
82                type_name,
83                component,
84                value,
85            } => write!(
86                formatter,
87                "{type_name} {component} component must be finite, got {value}"
88            ),
89            Self::NegativeRadius(value) => {
90                write!(formatter, "circle radius must be non-negative, got {value}")
91            },
92            Self::NonFiniteRadius(value) => {
93                write!(formatter, "circle radius must be finite, got {value}")
94            },
95            Self::NonFiniteTolerance(value) => {
96                write!(formatter, "tolerance must be finite, got {value}")
97            },
98            Self::NegativeTolerance(value) => {
99                write!(formatter, "tolerance must be non-negative, got {value}")
100            },
101            Self::IdenticalPoints => write!(formatter, "points must be distinct"),
102            Self::ZeroDirectionVector => write!(formatter, "direction vector must be non-zero"),
103            Self::InvalidBounds {
104                min_x,
105                min_y,
106                max_x,
107                max_y,
108            } => write!(
109                formatter,
110                "aabb min must not exceed max, got min=({min_x}, {min_y}) and max=({max_x}, {max_y})"
111            ),
112        }
113    }
114}
115
116impl Error for GeometryError {}