fits_header/error.rs
1//! Error type for fallible header operations.
2
3/// A `Result` whose error is always [`FitsError`].
4pub type Result<T> = std::result::Result<T, FitsError>;
5
6/// Errors from validated header mutations, ambiguous lookups, and oversized standalone
7/// serialization.
8///
9/// Parsing is lenient and does not produce these; header-only serialization
10/// ([`Header::to_header_bytes`](crate::Header::to_header_bytes)) is infallible.
11///
12/// # Examples
13///
14/// ```
15/// # use fits_header::{FitsError, Header};
16/// let mut h = Header::new();
17/// h.append("GAIN", 1).unwrap();
18/// h.append("GAIN", 2).unwrap();
19/// assert!(matches!(
20/// h.get::<i64>("GAIN"),
21/// Err(FitsError::AmbiguousKeyword { .. })
22/// ));
23/// ```
24#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
25#[non_exhaustive]
26pub enum FitsError {
27 /// A bare-name `get`/`set`/`remove` addressed a keyword that occurs more than once.
28 /// Select one with an `(name, occurrence)` key.
29 #[error("keyword '{keyword}' occurs {count} times; select an occurrence")]
30 AmbiguousKeyword {
31 /// The duplicated keyword.
32 keyword: String,
33 /// How many times it occurs.
34 count: usize,
35 },
36
37 /// A keyword longer than the 8-character FITS field.
38 #[error("keyword '{keyword}' exceeds 8 characters")]
39 KeywordTooLong {
40 /// The offending keyword.
41 keyword: String,
42 },
43
44 /// A keyword containing bytes outside the FITS keyword set (`A-Z 0-9 - _`).
45 #[error("keyword '{keyword}' contains characters outside A-Z 0-9 - _")]
46 InvalidKeyword {
47 /// The offending keyword.
48 keyword: String,
49 },
50
51 /// An `(name, occurrence)` key targeted an occurrence that does not exist.
52 #[error("keyword '{keyword}' has no occurrence {occurrence} (found {count})")]
53 OccurrenceOutOfRange {
54 /// The keyword addressed.
55 keyword: String,
56 /// The 0-based occurrence requested.
57 occurrence: usize,
58 /// How many occurrences exist.
59 count: usize,
60 },
61
62 /// [`Header::update_file`](crate::Header::update_file) found no `END` card in the
63 /// existing file's header region, so the data unit's boundary cannot be located.
64 #[error("no END card found in header")]
65 MissingEnd,
66
67 /// [`Header::update_file`](crate::Header::update_file) found an `END` card, but the file
68 /// ends before that header's 2880-byte block is complete — a truncated FITS file.
69 #[error("header ends before its 2880-byte block is complete (truncated file)")]
70 TruncatedHeader,
71
72 /// A file read or write failed ([`Header::read_from_file`](crate::Header::read_from_file),
73 /// [`Header::update_file`](crate::Header::update_file)).
74 #[error("I/O error: {0}")]
75 Io(String),
76}
77
78impl From<std::io::Error> for FitsError {
79 fn from(e: std::io::Error) -> Self {
80 FitsError::Io(e.to_string())
81 }
82}