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}