axiolid_linear_intersection/
error.rs

1//! Typed refusals for linear intersection.
2//!
3//! Every failure names which operand caused it. A caller repairing input data
4//! cannot act on "something was invalid".
5
6/// Which operand a diagnostic refers to.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum InputSide {
9    /// The first operand.
10    Left,
11    /// The second operand.
12    Right,
13}
14
15/// Why a linear intersection could not be answered.
16///
17/// These are refusals, not results: none of them may be interpreted as
18/// "no intersection". A disjoint configuration is a successful classification.
19#[non_exhaustive]
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21pub enum LinearIntersectionError {
22    /// An operand carried a non-finite coordinate or direction component.
23    NonFiniteInput {
24        /// Operand at fault.
25        side: InputSide,
26    },
27    /// An operand's direction was zero, so it does not define a line.
28    DegenerateDirection {
29        /// Operand at fault.
30        side: InputSide,
31    },
32    /// An intermediate value left the finite range, so no sign is provable.
33    ArithmeticOverflow,
34}
35
36impl core::fmt::Display for LinearIntersectionError {
37    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38        match self {
39            Self::NonFiniteInput { side } => write!(f, "{side:?} operand has non-finite input"),
40            Self::DegenerateDirection { side } => {
41                write!(f, "{side:?} operand has a zero-length direction")
42            }
43            Self::ArithmeticOverflow => {
44                f.write_str("intersection arithmetic left the finite range")
45            }
46        }
47    }
48}
49
50impl std::error::Error for LinearIntersectionError {}