Skip to main content

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}