1use crate::{Kmer, MerImmut};
2
3pub struct KmerOneHammingIter<K>
5where
6 K: Kmer,
7{
8 source: K, position: usize, char: u8, }
12
13impl<K> KmerOneHammingIter<K>
14where
15 K: Kmer,
16{
17 pub fn new(kmer: K) -> Self {
19 KmerOneHammingIter {
20 source: kmer,
21 position: 0,
22 char: 0,
23 }
24 }
25}
26
27impl<K> Iterator for KmerOneHammingIter<K>
28where
29 K: Kmer,
30{
31 type Item = K;
32
33 fn next(&mut self) -> Option<Self::Item> {
34 if self.position >= self.source.len() {
35 return None;
36 }
37 let base_at_pos = self.source.get(self.position);
38
39 if self.char >= 4 {
40 self.position += 1;
41 self.char = 0;
42 self.next()
43 } else if base_at_pos == self.char {
44 self.char += 1;
45 self.next()
46 } else {
47 let next_sseq = self.source.set(self.position, self.char);
48 self.char += 1;
49 Some(next_sseq)
50 }
51 }
52}
53
54#[cfg(test)]
55mod test {
56 use super::*;
57 use crate::kmer::Kmer12;
58 use crate::Kmer;
59
60 #[test]
61 fn test_hd1() {
62 let k1 = Kmer12::from_ascii(b"AAAGGGTTTCCC");
63
64 let mut hd1: Vec<_> = KmerOneHammingIter::new(k1).collect();
65 assert_eq!(hd1.len(), 12 * 3);
66
67 hd1.sort();
68 hd1.dedup();
69 assert_eq!(hd1.len(), 12 * 3);
70
71 for k in &hd1 {
72 assert_eq!(k1.hamming_dist(*k), 1);
73 }
74 }
75}