target_match/error.rs
1//! Error type for `target-match`.
2//!
3//! Every fallible entry point returns [`Result`]. The only construction this
4//! crate itself validates is optics/field geometry — coordinate parsing and
5//! domain checks happen in [`skymath`] when the consumer builds an
6//! [`skymath::Equatorial`], and surface as [`skymath::Error`]. Matching and
7//! precession are infallible once inputs are valid values.
8
9use thiserror::Error;
10
11/// Everything that can go wrong constructing `target-match` values.
12///
13/// # Example
14///
15/// ```
16/// use target_match::{Error, Field, Optics};
17///
18/// let err = Field::from_optics(Optics {
19/// focal_mm: 0.0, pixel_um: (3.76, 3.76), binning: (1, 1), pixels: (6248, 4176),
20/// })
21/// .unwrap_err();
22/// assert!(matches!(err, Error::InvalidOptics(_)));
23/// ```
24#[derive(Debug, Clone, PartialEq, Error)]
25#[non_exhaustive]
26pub enum Error {
27 /// Optics or field inputs were non-positive, non-finite, or insufficient to
28 /// derive a field of view.
29 #[error("invalid optics: {0}")]
30 InvalidOptics(String),
31}
32
33/// Convenience alias for `Result<T, `[`Error`](enum@Error)`>`.
34pub type Result<T> = core::result::Result<T, Error>;
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn display_messages() {
42 assert_eq!(
43 Error::InvalidOptics("focal <= 0".into()).to_string(),
44 "invalid optics: focal <= 0"
45 );
46 }
47}