Skip to main content

hpr_core/
error.rs

1//! Error types shared by the core crate.
2
3use thiserror::Error;
4
5/// An error from a core model: a table that can't be built, a lookup it refuses, or an input
6/// outside a model's domain.
7#[derive(Debug, Clone, PartialEq, Error)]
8#[non_exhaustive]
9pub enum CoreError {
10    /// A table needs at least `min` knots.
11    #[error("a table needs at least {min} knots, got {got}")]
12    TableTooShort {
13        /// The minimum number of knots.
14        min: usize,
15        /// The number supplied.
16        got: usize,
17    },
18    /// The abscissa and ordinate columns have different lengths.
19    #[error("table columns differ in length: {xs} abscissae, {ys} ordinates")]
20    TableLengthMismatch {
21        /// Number of abscissae.
22        xs: usize,
23        /// Number of ordinates.
24        ys: usize,
25    },
26    /// A table value is NaN or infinite.
27    #[error("table value at index {index} is not finite")]
28    TableNotFinite {
29        /// Index of the offending knot.
30        index: usize,
31    },
32    /// Abscissae must strictly increase.
33    #[error("table abscissae must strictly increase; index {index} does not")]
34    TableNotIncreasing {
35        /// Index of the first abscissa that is not greater than its predecessor.
36        index: usize,
37    },
38    /// A lookup outside the table, on a table whose policy is [`crate::interp::Extrapolation::Error`].
39    #[error("lookup at {x} is outside the table range [{min}, {max}]")]
40    OutOfRange {
41        /// The requested abscissa.
42        x: f64,
43        /// The first abscissa.
44        min: f64,
45        /// The last abscissa.
46        max: f64,
47    },
48    /// An interval's width, its secant slope or a spline slope overflows `f64`.
49    #[error("table interval {interval} overflows: its width or slope is not a finite f64")]
50    TableOverflow {
51        /// Index of the interval `[x_i, x_{i+1}]`.
52        interval: usize,
53    },
54    /// Linear extrapolation gave a value that is not finite.
55    #[error("linear extrapolation to {x} does not give a finite value")]
56    ExtrapolationOverflow {
57        /// The requested abscissa.
58        x: f64,
59    },
60    /// A lookup at NaN.
61    #[error("lookup at NaN")]
62    NanLookup,
63    /// A serialized random generator state that is not four `0x`-prefixed hexadecimal 64-bit
64    /// words, or is all zero.
65    #[error("a random generator state must be four 0x-prefixed 64-bit hex words, not all zero")]
66    InvalidRandomState,
67    /// An integrand returned NaN or an infinity.
68    #[error("the integrand is not finite at {x}")]
69    QuadratureNotFinite {
70        /// Where the integrand was evaluated.
71        x: f64,
72    },
73    /// Adaptive integration didn't meet its tolerance within its subinterval budget.
74    #[error(
75        "integration did not converge: component {component} is {value} with error estimate {error} after {intervals} subintervals"
76    )]
77    QuadratureDidNotConverge {
78        /// The component furthest from its tolerance.
79        component: usize,
80        /// Its best estimate.
81        value: f64,
82        /// Its error estimate.
83        error: f64,
84        /// The subintervals used.
85        intervals: usize,
86    },
87    /// An input outside a model's domain, such as a latitude beyond ±90°.
88    #[error("{what} is outside its domain: {value}")]
89    Domain {
90        /// What the value is.
91        what: &'static str,
92        /// The offending value.
93        value: f64,
94    },
95}