Skip to main content

dotloom_geometry/
error.rs

1use thiserror::Error;
2
3/// Errors produced by geometry operations.
4///
5/// Geometry functions never panic on bad input; they return one of these explicit
6/// results instead (non-finite numbers, degenerate shapes, unsupported transforms, ...).
7#[derive(Debug, Clone, PartialEq, Error)]
8#[non_exhaustive]
9pub enum GeometryError {
10    /// An input coordinate or parameter was NaN or infinite.
11    #[error("non-finite value in {0}")]
12    NonFinite(&'static str),
13    /// The shape has no extent where one is required (zero-length segment, zero radius, ...).
14    #[error("degenerate geometry: {0}")]
15    Degenerate(&'static str),
16    /// The transform has a (near) zero determinant and cannot be inverted.
17    #[error("singular transform (determinant {determinant:e})")]
18    SingularTransform {
19        /// Determinant of the linear part.
20        determinant: f64,
21    },
22    /// The transform cannot be applied while keeping the shape's semantics
23    /// (for example a non-uniform scale applied to a circle).
24    #[error("unsupported transform for {shape}: {reason}")]
25    UnsupportedTransform {
26        /// Shape kind name.
27        shape: &'static str,
28        /// Human readable reason.
29        reason: &'static str,
30    },
31    /// The requested operation is not defined for this shape kind.
32    #[error("operation `{operation}` is not supported for {shape}")]
33    UnsupportedOperation {
34        /// Operation name.
35        operation: &'static str,
36        /// Shape kind name.
37        shape: &'static str,
38    },
39    /// No intersection or boundary was found where the operation needs one.
40    #[error("no boundary found: {0}")]
41    NoBoundary(&'static str),
42    /// A parameter is outside its valid range.
43    #[error("invalid argument: {0}")]
44    InvalidArgument(&'static str),
45    /// Two quantities with different physical dimensions were combined.
46    #[error("dimension mismatch: {left} vs {right}")]
47    DimensionMismatch {
48        /// Left operand dimension.
49        left: String,
50        /// Right operand dimension.
51        right: String,
52    },
53    /// A unit string could not be parsed.
54    #[error("unknown unit `{0}`")]
55    UnknownUnit(String),
56}
57
58/// Result alias for geometry operations.
59pub type GeoResult<T> = Result<T, GeometryError>;
60
61pub(crate) fn finite(v: f64, what: &'static str) -> GeoResult<f64> {
62    if v.is_finite() { Ok(v) } else { Err(GeometryError::NonFinite(what)) }
63}