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 {}