bio_seq/codec/masked/
iupac.rs1use crate::codec::Codec;
2use crate::{ComplementMut, Maskable, MaskableMut}; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Codec)]
8#[bits(5)]
9#[repr(u8)]
10pub enum Iupac {
11 A = 0b10000,
12 C = 0b01000,
13 G = 0b00010,
14 T = 0b00001,
15
16 Y = 0b01001,
17 R = 0b10010,
18 W = 0b10001,
19 S = 0b01010,
20
21 K = 0b00011,
22 M = 0b11000,
23 D = 0b10011,
24 V = 0b11010,
25
26 H = 0b11001,
27 B = 0b01011,
28
29 N = 0b11011,
30 #[display('-')]
31 X = 0b00000,
32
33 #[display('a')]
34 AMasked = 0b10100,
35 #[display('c')]
36 CMasked = 0b01100,
37 #[display('g')]
38 GMasked = 0b00110,
39 #[display('t')]
40 TMasked = 0b00101,
41
42 #[display('y')]
43 YMasked = 0b01101,
44 #[display('r')]
45 RMasked = 0b10110,
46 #[display('w')]
47 WMasked = 0b10101,
48 #[display('s')]
49 SMasked = 0b01110,
50
51 #[display('k')]
52 KMasked = 0b00111,
53 #[display('m')]
54 MMasked = 0b11100,
55 #[display('d')]
56 DMasked = 0b10111,
57 #[display('v')]
58 VMasked = 0b11110,
59
60 #[display('h')]
61 HMasked = 0b11101,
62 #[display('b')]
63 BMasked = 0b01111,
64
65 #[display('n')]
66 NMasked = 0b11111,
67 #[display('.')]
68 XMasked = 0b00100,
69}
70
71impl ComplementMut for Iupac {
72 fn comp(&mut self) {
74 let bits = self.to_bits();
75 *self = Self::unsafe_from_bits(
76 ((bits & 0b10000) >> 4)
77 | ((bits & 0b01000) >> 2)
78 | (bits & 0b00100)
79 | ((bits & 0b00010) << 2)
80 | ((bits & 0b00001) << 4),
81 );
82 }
83}
84
85impl MaskableMut for Iupac {
86 fn mask(&mut self) {
88 let b = *self as u8 | 0b00100;
89 *self = Self::unsafe_from_bits(b);
90 }
91
92 fn unmask(&mut self) {
94 let b = *self as u8 & 0b11011;
95 *self = Self::unsafe_from_bits(b);
96 }
97}
98
99impl Maskable for Iupac {}
100
101#[cfg(test)]
102mod tests {
103 use crate::codec::masked;
104 use crate::prelude::*;
105
106 #[test]
107 fn mask_iupac_seq() {
108 let mut seq = Seq::<masked::Iupac>::try_from("A.TCGCgtcataN--A").unwrap();
109
110 assert_eq!(seq.to_mask().to_string(), "a.tcgcgtcatan..a".to_string());
111
112 seq.mask();
113 assert_eq!(seq.to_unmask().to_string(), "A-TCGCGTCATAN--A".to_string());
114 seq.unmask();
115 assert_eq!(seq.to_mask().to_string(), "a.tcgcgtcatan..a".to_string());
116 }
117
118 #[test]
119 fn comp_iupac_seq() {
120 let mut seq = Seq::<masked::Iupac>::try_from("A.TCGCgtcataN--A").unwrap();
121
122 assert_ne!(seq.to_comp().to_string(), "A.TCGCgtcataN--A".to_string());
123 assert_eq!(seq.to_comp().to_string(), "T.AGCGcagtatN--T".to_string());
124
125 seq.comp();
126 assert_eq!(seq.to_comp().to_string(), "A.TCGCgtcataN--A".to_string());
127 }
128}