target_match/error.rs
1//! Error type for `target-match`.
2//!
3//! Every fallible entry point returns [`Result`]. Errors arise only at the
4//! *construction* boundary — parsing coordinates, validating coordinate domains,
5//! and validating optics. Matching and precession are infallible once inputs are
6//! valid values (an [`crate::Equatorial`] always carries a fully-specified epoch,
7//! so there is no "epoch could not be resolved" runtime failure).
8
9use thiserror::Error;
10
11/// Everything that can go wrong constructing `target-match` values.
12#[derive(Debug, Clone, PartialEq, Error)]
13#[non_exhaustive]
14pub enum Error {
15 /// A coordinate string could not be parsed (empty, non-numeric, malformed
16 /// sexagesimal, or negative minutes/seconds).
17 #[error("could not parse coordinate: {0}")]
18 ParseCoord(String),
19
20 /// A numeric coordinate or epoch was outside its valid domain
21 /// (RA `[0, 360)`, Dec `[-90, 90]`, or a non-finite epoch year).
22 #[error("{what} out of range: {value}")]
23 OutOfRange {
24 /// Which quantity was out of range (e.g. `"right ascension"`).
25 what: &'static str,
26 /// The offending value.
27 value: f64,
28 },
29
30 /// Optics or field inputs were non-positive, non-finite, or insufficient to
31 /// derive a field of view.
32 #[error("invalid optics: {0}")]
33 InvalidOptics(String),
34}
35
36/// Convenience alias for `Result<T, `[`Error`](enum@Error)`>`.
37pub type Result<T> = core::result::Result<T, Error>;
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn display_messages() {
45 assert_eq!(
46 Error::ParseCoord("x".into()).to_string(),
47 "could not parse coordinate: x"
48 );
49 assert_eq!(
50 Error::OutOfRange {
51 what: "declination",
52 value: 91.0
53 }
54 .to_string(),
55 "declination out of range: 91"
56 );
57 assert_eq!(
58 Error::InvalidOptics("focal <= 0".into()).to_string(),
59 "invalid optics: focal <= 0"
60 );
61 }
62}