skydive/
link.rs

1use std::collections::VecDeque;
2use std::fmt;
3
4use needletail::sequence::complement;
5
6use parquet::data_type::AsBytes;
7
8/// Represents metadata on a link (a series of junction choices in de Bruijn graph).
9#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
10pub struct Link {
11    pub is_forward: bool,
12    pub junctions: VecDeque<u8>,
13}
14
15impl Link {
16    /// Create an empty link record.
17    #[must_use]
18    pub fn new(is_forward: bool) -> Self {
19        Link {
20            is_forward,
21            junctions: VecDeque::new(),
22        }
23    }
24
25    /// Create a link from a sequence of junction choices.
26    #[must_use]
27    pub fn from_junctions(is_forward: bool, seq: &[u8]) -> Self {
28        Link {
29            is_forward,
30            junctions: VecDeque::from(seq.to_vec()),
31        }
32    }
33
34    /// Return orientation of the link.
35    #[must_use]
36    pub fn is_forward(&self) -> bool {
37        self.is_forward
38    }
39
40    /// Return the number of junction choices in the link.
41    #[must_use]
42    pub fn len(&self) -> usize {
43        self.junctions.len()
44    }
45
46    /// Indicate whether the list of junctions is empty.
47    #[must_use]
48    pub fn is_empty(&self) -> bool {
49        self.junctions.is_empty()
50    }
51
52    /// Add a junction to the queue.
53    pub fn push_back(&mut self, junction: u8) {
54        self.junctions.push_back(junction);
55    }
56
57    /// Peek at a junction from the front of the queue.
58    #[must_use]
59    pub fn front(&self) -> Option<&u8> {
60        self.junctions.front()
61    }
62
63    /// Take a junction from the front of the queue.
64    pub fn pop_front(&mut self) -> Option<u8> {
65        self.junctions.pop_front()
66    }
67
68    /// Return a new link with the junction choices complemented.
69    #[must_use]
70    pub fn complement(&self) -> Link {
71        let mut new_link = Link::new(self.is_forward);
72
73        for junction in &self.junctions {
74            new_link.push_back(complement(*junction));
75        }
76
77        new_link
78    }
79}
80
81impl fmt::Display for Link {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        let mut jvec = Vec::new();
84        for junction in &self.junctions {
85            jvec.push(*junction);
86        }
87
88        write!(
89            f,
90            "{} {:?}",
91            if self.is_forward { "F" } else { "R" },
92            std::str::from_utf8(jvec.as_bytes())
93        )
94    }
95}