Skip to main content

xisf_header/
key.rs

1//! The unified [`Key`] used to address keywords.
2
3/// Addresses a keyword either by name (strict: it must be unique) or by a
4/// specific occurrence when a name repeats.
5///
6/// You rarely name `Key` directly — every keyword accessor takes
7/// `impl Into<Key>`, so both forms work:
8///
9/// ```
10/// use xisf_header::Header;
11/// let mut h = Header::new();
12/// h.append("HISTORY", "first").unwrap();
13/// h.append("HISTORY", "second").unwrap();
14///
15/// // Bare name is ambiguous here → error; select an occurrence instead.
16/// assert!(h.get_str("HISTORY").is_err());
17/// assert_eq!(h.get_str(("HISTORY", 1)).unwrap(), Some("second"));
18/// ```
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum Key<'a> {
21    /// Match the sole keyword with this name (ambiguous if it repeats).
22    Name(&'a str),
23    /// Match the `usize`-th (0-based) occurrence of this name.
24    Nth(&'a str, usize),
25}
26
27impl<'a> Key<'a> {
28    /// The keyword name this key addresses.
29    ///
30    /// ```
31    /// use xisf_header::Key;
32    ///
33    /// let key: Key = ("HISTORY", 1).into();
34    /// assert_eq!(key.name(), "HISTORY");
35    /// ```
36    #[must_use]
37    pub fn name(&self) -> &'a str {
38        match *self {
39            Key::Name(n) | Key::Nth(n, _) => n,
40        }
41    }
42}
43
44impl<'a> From<&'a str> for Key<'a> {
45    fn from(name: &'a str) -> Self {
46        Key::Name(name)
47    }
48}
49
50impl<'a> From<&'a String> for Key<'a> {
51    fn from(name: &'a String) -> Self {
52        Key::Name(name)
53    }
54}
55
56impl<'a> From<(&'a str, usize)> for Key<'a> {
57    fn from((name, n): (&'a str, usize)) -> Self {
58        Key::Nth(name, n)
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn conversions_and_name() {
68        let by_name: Key = "GAIN".into();
69        assert_eq!(by_name, Key::Name("GAIN"));
70        assert_eq!(by_name.name(), "GAIN");
71
72        let owned = String::from("GAIN");
73        let from_string: Key = (&owned).into();
74        assert_eq!(from_string, Key::Name("GAIN"));
75
76        let nth: Key = ("HISTORY", 2).into();
77        assert_eq!(nth, Key::Nth("HISTORY", 2));
78        assert_eq!(nth.name(), "HISTORY");
79    }
80}