omics_coordinate/
contig.rs

1//! Contiguous molecules.
2
3use std::convert::Infallible;
4
5////////////////////////////////////////////////////////////////////////////////////////
6// Contig
7////////////////////////////////////////////////////////////////////////////////////////
8
9/// A named, contiguous molecule within a genome.
10///
11/// At present, a contig is simply a wrapper around a string. Empty contig names
12/// are allowed though not recommended.
13///
14/// Notably, the internal representation of [`Contig`] may change in the future
15/// (though the interface to this type will remain stable with respect to
16/// [semantic versioning](https://semver.org/)).
17///
18/// For a more in-depth discussion on this, please see [this section of the
19/// docs](crate#contigs).
20#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
21pub struct Contig(String);
22
23impl Contig {
24    /// Attempts to create a new contig.
25    ///
26    /// # Examples
27    ///
28    /// ```
29    /// use omics_coordinate::Contig;
30    ///
31    /// let contig = Contig::new("chr1");
32    /// ```
33    pub fn new(value: impl Into<String>) -> Self {
34        Self(value.into())
35    }
36
37    // NOTE: an `inner()` method is explicitly not included as the type
38    // dereferences `String`. This means that the `as_str()` method is usable
39    // for this purpose.
40
41    /// Consumes `self` and returns the inner value.
42    ///
43    /// # Examples
44    ///
45    /// ```
46    /// use omics_coordinate::Contig;
47    ///
48    /// let contig = Contig::new("chr1");
49    /// assert_eq!(contig.into_inner(), String::from("chr1"));
50    /// ```
51    pub fn into_inner(self) -> String {
52        self.0
53    }
54}
55
56////////////////////////////////////////////////////////////////////////////////////////
57// Trait implementations
58////////////////////////////////////////////////////////////////////////////////////////
59
60impl std::fmt::Display for Contig {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        write!(f, "{}", self.0)
63    }
64}
65
66impl std::str::FromStr for Contig {
67    type Err = Infallible;
68
69    fn from_str(s: &str) -> Result<Self, Infallible> {
70        Ok(Self::new(s))
71    }
72}
73
74impl From<&str> for Contig {
75    fn from(value: &str) -> Self {
76        Self::new(value)
77    }
78}
79
80impl From<String> for Contig {
81    fn from(value: String) -> Self {
82        Self::new(value)
83    }
84}
85
86impl std::ops::Deref for Contig {
87    type Target = String;
88
89    fn deref(&self) -> &Self::Target {
90        &self.0
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97
98    #[test]
99    fn parse() {
100        let contig = "chr1".parse::<Contig>().expect("contig to parse");
101        assert_eq!(contig.as_str(), "chr1");
102    }
103}