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}