fits_header/key.rs
1//! Record selectors.
2
3/// Selects a record by keyword.
4///
5/// A bare name is **strict**: `get`/`set`/`remove` error with
6/// [`FitsError::AmbiguousKeyword`](crate::FitsError::AmbiguousKeyword) if the keyword is
7/// duplicated. The `(name, occurrence)` form targets exactly one record (0-based).
8///
9/// # Examples
10///
11/// ```
12/// # use fits_header::Header;
13/// let mut h = Header::new();
14/// h.append("GAIN", 100).unwrap();
15/// h.append("GAIN", 200).unwrap();
16///
17/// assert!(h.get::<i64>("GAIN").is_err()); // ambiguous bare name
18/// assert_eq!(h.get::<i64>(("GAIN", 1)).unwrap(), Some(200)); // explicit occurrence
19/// ```
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub enum Key {
22 /// The sole occurrence of a keyword (strict).
23 Name(String),
24 /// The n-th (0-based) occurrence of a keyword.
25 Occurrence(String, usize),
26}
27
28impl Key {
29 /// The keyword this key refers to.
30 ///
31 /// # Examples
32 ///
33 /// ```
34 /// # use fits_header::Key;
35 /// let bare: Key = "GAIN".into();
36 /// let occ: Key = ("GAIN", 1).into();
37 /// assert_eq!(bare.name(), "GAIN");
38 /// assert_eq!(occ.name(), "GAIN");
39 /// ```
40 pub fn name(&self) -> &str {
41 match self {
42 Key::Name(n) | Key::Occurrence(n, _) => n,
43 }
44 }
45
46 /// The selected occurrence index, if any.
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// # use fits_header::Key;
52 /// let bare: Key = "GAIN".into();
53 /// let occ: Key = ("GAIN", 1).into();
54 /// assert_eq!(bare.occurrence(), None);
55 /// assert_eq!(occ.occurrence(), Some(1));
56 /// ```
57 pub fn occurrence(&self) -> Option<usize> {
58 match self {
59 Key::Name(_) => None,
60 Key::Occurrence(_, n) => Some(*n),
61 }
62 }
63}
64
65impl From<&str> for Key {
66 fn from(name: &str) -> Self {
67 Key::Name(name.to_string())
68 }
69}
70
71impl From<String> for Key {
72 fn from(name: String) -> Self {
73 Key::Name(name)
74 }
75}
76
77impl From<&String> for Key {
78 fn from(name: &String) -> Self {
79 Key::Name(name.clone())
80 }
81}
82
83impl From<(&str, usize)> for Key {
84 fn from((name, n): (&str, usize)) -> Self {
85 Key::Occurrence(name.to_string(), n)
86 }
87}
88
89impl From<(String, usize)> for Key {
90 fn from((name, n): (String, usize)) -> Self {
91 Key::Occurrence(name, n)
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn conversions_and_accessors() {
101 let k: Key = "GAIN".into();
102 assert_eq!(k, Key::Name("GAIN".to_string()));
103 assert_eq!(k.name(), "GAIN");
104 assert_eq!(k.occurrence(), None);
105
106 let k: Key = ("GAIN".to_string()).into();
107 assert_eq!(k.name(), "GAIN");
108 let k: Key = (&"GAIN".to_string()).into();
109 assert_eq!(k.name(), "GAIN");
110
111 let k: Key = ("GAIN", 1).into();
112 assert_eq!(k, Key::Occurrence("GAIN".to_string(), 1));
113 assert_eq!(k.name(), "GAIN");
114 assert_eq!(k.occurrence(), Some(1));
115 let k: Key = ("GAIN".to_string(), 2).into();
116 assert_eq!(k.occurrence(), Some(2));
117 }
118}