path_traits/error.rs
1//! Error types for path operations.
2//!
3//! This module defines [`PathError<S>`], the canonical error enum for all path-related
4//! fallible operations. Every trait in the hierarchy exposes
5//! `type Error: From<PathError<Self::Scalar>>` so implementers may use their own error type.
6
7use crate::Scalar;
8use core::fmt;
9use core::ops::RangeInclusive;
10
11/// Errors that can occur during path sampling or geometric queries.
12///
13/// The scalar parameter `S` allows the error to carry the exact parameter value
14/// and domain that caused the failure, making diagnostics precise.
15#[non_exhaustive]
16#[derive(Debug, Clone, PartialEq)]
17pub enum PathError<S> {
18 /// Arc-length / parameter outside the valid domain.
19 OutOfDomain {
20 /// The parameter value that was out of domain.
21 param: S,
22 /// The valid domain `[start, end]`.
23 domain: RangeInclusive<S>,
24 },
25 /// The path is not differentiable at `param` (e.g. a cusp or kink).
26 NotDifferentiable {
27 /// The parameter where differentiability fails.
28 param: S,
29 /// Human-readable reason.
30 reason: &'static str,
31 },
32 /// The path is degenerate (e.g. zero-length segment, collinear control points).
33 Degenerate {
34 /// Human-readable reason.
35 reason: &'static str,
36 },
37 /// A custom error with a static description for implementer-specific failures.
38 Custom(&'static str),
39}
40
41impl<S: Scalar> PathError<S> {
42 /// Create an `OutOfDomain` error with the offending parameter and valid domain.
43 pub fn out_of_domain(param: S, domain: RangeInclusive<S>) -> Self {
44 PathError::OutOfDomain { param, domain }
45 }
46
47 /// Create a `NotDifferentiable` error with the parameter and reason.
48 pub fn not_differentiable(param: S, reason: &'static str) -> Self {
49 PathError::NotDifferentiable { param, reason }
50 }
51
52 /// Create a `Degenerate` error with a reason.
53 pub fn degenerate(reason: &'static str) -> Self {
54 PathError::Degenerate { reason }
55 }
56}
57
58impl<S: fmt::Debug> fmt::Display for PathError<S> {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 match self {
61 PathError::OutOfDomain { param, domain } => {
62 write!(
63 f,
64 "parameter {:?} is outside the valid domain {:?}",
65 param, domain
66 )
67 }
68 PathError::NotDifferentiable { param, reason } => {
69 write!(f, "path is not differentiable at {:?}: {}", param, reason)
70 }
71 PathError::Degenerate { reason } => {
72 write!(f, "path is degenerate: {}", reason)
73 }
74 PathError::Custom(msg) => write!(f, "{}", msg),
75 }
76 }
77}
78
79impl<S: fmt::Debug> core::error::Error for PathError<S> {}