noodles_vcf/header/record/
key.rs

1//! VCF header record key.
2
3pub mod other;
4
5pub use self::other::Other;
6
7use std::fmt;
8
9/// VCF header record file format key.
10pub const FILE_FORMAT: Key = Key::Standard(Standard::FileFormat);
11
12/// VCF header record info key.
13pub const INFO: Key = Key::Standard(Standard::Info);
14
15/// VCF header record filter key.
16pub const FILTER: Key = Key::Standard(Standard::Filter);
17
18/// VCF header record format key.
19pub const FORMAT: Key = Key::Standard(Standard::Format);
20
21/// VCF header record alternative allele key.
22pub const ALTERNATIVE_ALLELE: Key = Key::Standard(Standard::AlternativeAllele);
23
24/// VCF header record contig key.
25pub const CONTIG: Key = Key::Standard(Standard::Contig);
26
27/// A standard VCF record key.
28#[derive(Clone, Debug, Eq, Hash, PartialEq)]
29pub enum Standard {
30    /// File format (`fileformat`).
31    FileFormat,
32    /// Information (`INFO`).
33    Info,
34    /// Filter (`FILTER`)
35    Filter,
36    /// Genotype format (`FORMAT`).
37    Format,
38    /// Symbolic alternate allele (`ALT`).
39    AlternativeAllele,
40    /// Contig (`contig`).
41    Contig,
42}
43
44impl Standard {
45    fn new(s: &str) -> Option<Self> {
46        match s {
47            "fileformat" => Some(Self::FileFormat),
48            "INFO" => Some(Self::Info),
49            "FILTER" => Some(Self::Filter),
50            "FORMAT" => Some(Self::Format),
51            "ALT" => Some(Self::AlternativeAllele),
52            "contig" => Some(Self::Contig),
53            _ => None,
54        }
55    }
56}
57
58impl AsRef<str> for Standard {
59    fn as_ref(&self) -> &str {
60        match self {
61            Self::FileFormat => "fileformat",
62            Self::Info => "INFO",
63            Self::Filter => "FILTER",
64            Self::Format => "FORMAT",
65            Self::AlternativeAllele => "ALT",
66            Self::Contig => "contig",
67        }
68    }
69}
70
71impl fmt::Display for Standard {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        self.as_ref().fmt(f)
74    }
75}
76
77/// A VCF header record key.
78#[derive(Clone, Debug, Eq, Hash, PartialEq)]
79pub enum Key {
80    /// A standard key.
81    Standard(Standard),
82    /// Any nonstandard key.
83    Other(Other),
84}
85
86impl Key {
87    /// Creates a nonstandard key.
88    ///
89    /// # Examples
90    ///
91    /// ```
92    /// use noodles_vcf::header::record::Key;
93    /// assert!(Key::other("INFO").is_none());
94    /// assert!(Key::other("fileDate").is_some());
95    /// ```
96    pub fn other(s: &str) -> Option<Other> {
97        match Self::from(s) {
98            Self::Standard(_) => None,
99            Self::Other(tag) => Some(tag),
100        }
101    }
102}
103
104impl AsRef<str> for Key {
105    fn as_ref(&self) -> &str {
106        match self {
107            Self::Standard(tag) => tag.as_ref(),
108            Self::Other(tag) => tag.as_ref(),
109        }
110    }
111}
112
113impl fmt::Display for Key {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        self.as_ref().fmt(f)
116    }
117}
118
119impl From<&str> for Key {
120    fn from(s: &str) -> Self {
121        match Standard::new(s) {
122            Some(tag) => Self::Standard(tag),
123            None => Self::Other(Other(s.into())),
124        }
125    }
126}
127
128impl From<String> for Key {
129    fn from(s: String) -> Self {
130        match Standard::new(&s) {
131            Some(tag) => Self::Standard(tag),
132            None => Self::Other(Other(s)),
133        }
134    }
135}
136
137#[cfg(test)]
138mod tests {
139    use super::*;
140
141    #[test]
142    fn test_fmt() {
143        assert_eq!(FILE_FORMAT.to_string(), "fileformat");
144        assert_eq!(INFO.to_string(), "INFO");
145        assert_eq!(FILTER.to_string(), "FILTER");
146        assert_eq!(FORMAT.to_string(), "FORMAT");
147        assert_eq!(ALTERNATIVE_ALLELE.to_string(), "ALT");
148        assert_eq!(CONTIG.to_string(), "contig");
149        assert_eq!(
150            Key::Other(Other(String::from("fileDate"))).to_string(),
151            "fileDate"
152        );
153    }
154
155    #[test]
156    fn test_from() {
157        assert_eq!(Key::from("fileformat"), FILE_FORMAT);
158        assert_eq!(Key::from("INFO"), INFO);
159        assert_eq!(Key::from("FILTER"), FILTER);
160        assert_eq!(Key::from("FORMAT"), FORMAT);
161        assert_eq!(Key::from("ALT"), ALTERNATIVE_ALLELE);
162        assert_eq!(Key::from("contig"), CONTIG);
163        assert_eq!(
164            Key::from("fileDate"),
165            Key::Other(Other(String::from("fileDate")))
166        );
167    }
168}