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    pub fn name(&self) -> &str {
31        match self {
32            Key::Name(n) | Key::Occurrence(n, _) => n,
33        }
34    }
35
36    /// The selected occurrence index, if any.
37    pub fn occurrence(&self) -> Option<usize> {
38        match self {
39            Key::Name(_) => None,
40            Key::Occurrence(_, n) => Some(*n),
41        }
42    }
43}
44
45impl From<&str> for Key {
46    fn from(name: &str) -> Self {
47        Key::Name(name.to_string())
48    }
49}
50
51impl From<String> for Key {
52    fn from(name: String) -> Self {
53        Key::Name(name)
54    }
55}
56
57impl From<&String> for Key {
58    fn from(name: &String) -> Self {
59        Key::Name(name.clone())
60    }
61}
62
63impl From<(&str, usize)> for Key {
64    fn from((name, n): (&str, usize)) -> Self {
65        Key::Occurrence(name.to_string(), n)
66    }
67}
68
69impl From<(String, usize)> for Key {
70    fn from((name, n): (String, usize)) -> Self {
71        Key::Occurrence(name, n)
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    #[test]
80    fn conversions_and_accessors() {
81        let k: Key = "GAIN".into();
82        assert_eq!(k, Key::Name("GAIN".to_string()));
83        assert_eq!(k.name(), "GAIN");
84        assert_eq!(k.occurrence(), None);
85
86        let k: Key = ("GAIN".to_string()).into();
87        assert_eq!(k.name(), "GAIN");
88        let k: Key = (&"GAIN".to_string()).into();
89        assert_eq!(k.name(), "GAIN");
90
91        let k: Key = ("GAIN", 1).into();
92        assert_eq!(k, Key::Occurrence("GAIN".to_string(), 1));
93        assert_eq!(k.name(), "GAIN");
94        assert_eq!(k.occurrence(), Some(1));
95        let k: Key = ("GAIN".to_string(), 2).into();
96        assert_eq!(k.occurrence(), Some(2));
97    }
98}