kff/utils/
read.rs

1//! Utils function to read KFF
2
3/* std use */
4
5/* crate use */
6
7/* project use */
8use crate::error;
9
10/// Define trait containts utils function to parsing kff
11pub trait KffRead {
12    /// Function read N bytes (N define at compile time) in a readable
13    fn read_n_bytes<const N: usize>(&mut self) -> error::Result<[u8; N]>;
14
15    /// Function read N bytes (N define at run time) in a readable
16    fn read_n_bytes_dyn(&mut self, n: usize) -> error::Result<Vec<u8>>;
17
18    /// Function read a Kff 'ascii'
19    fn read_ascii(&mut self) -> error::Result<Vec<u8>>;
20
21    /// Function some base in 2bits representation
22    fn read_2bits(
23        &mut self,
24        k: usize,
25    ) -> error::Result<bitvec::vec::BitVec<u8, bitvec::order::Msb0>>;
26
27    /// Function that read one bit and convert it as bool
28    fn read_bool(&mut self) -> error::Result<bool> {
29        self.read_u8().map(|x| x != 0)
30    }
31
32    /// Function that read u8
33    fn read_u8(&mut self) -> error::Result<u8> {
34        self.read_n_bytes::<1>()
35            .map(|x| unsafe { *x.get_unchecked(0) })
36    }
37
38    /// Function that read u16
39    fn read_u16(&mut self) -> error::Result<u16> {
40        self.read_n_bytes::<2>().map(u16::from_be_bytes)
41    }
42
43    /// Function that read u32
44    fn read_u32(&mut self) -> error::Result<u32> {
45        self.read_n_bytes::<4>().map(u32::from_be_bytes)
46    }
47
48    /// Function that read u64
49    fn read_u64(&mut self) -> error::Result<u64> {
50        self.read_n_bytes::<8>().map(u64::from_be_bytes)
51    }
52
53    /// Function that read i64
54    fn read_i64(&mut self) -> error::Result<i64> {
55        self.read_n_bytes::<8>().map(i64::from_be_bytes)
56    }
57}
58
59impl<T> KffRead for T
60where
61    T: std::io::BufRead,
62{
63    fn read_n_bytes<const N: usize>(&mut self) -> error::Result<[u8; N]> {
64        let mut values = [0; N];
65
66        self.read_exact(&mut values)?;
67
68        Ok(values)
69    }
70
71    fn read_n_bytes_dyn(&mut self, n: usize) -> error::Result<Vec<u8>> {
72        let mut values = vec![0; n];
73
74        self.read_exact(&mut values)?;
75
76        Ok(values)
77    }
78
79    fn read_ascii(&mut self) -> error::Result<Vec<u8>> {
80        let mut values = Vec::with_capacity(50);
81
82        self.read_until(0, &mut values)?;
83
84        if let Some(0) = values.last() {
85            values.pop();
86        }
87
88        Ok(values)
89    }
90
91    fn read_2bits(
92        &mut self,
93        k: usize,
94    ) -> error::Result<bitvec::vec::BitVec<u8, bitvec::order::Msb0>> {
95        let mut values = bitvec::vec::BitVec::from_slice(
96            &self.read_n_bytes_dyn(crate::bytes2store_k(k as u64) as usize)?,
97        );
98
99        values.resize(k * 2, false);
100
101        Ok(values)
102    }
103}
104
105#[cfg(test)]
106mod tests {
107    use super::*;
108
109    use std::io::Seek;
110
111    const LOREM: &[u8] = b"Lorem ipsum dolor\0sit amet, consectetur adipiscing elit.";
112
113    #[test]
114    fn read_n_bytes() -> error::Result<()> {
115        let mut reader = std::io::Cursor::new(LOREM);
116
117        let values = reader.read_n_bytes::<11>()?;
118
119        assert_eq!(&values, b"Lorem ipsum");
120
121        let values = reader.read_n_bytes::<11>()?;
122
123        assert_eq!(&values, b" dolor\0sit ");
124
125        let values = reader.read_n_bytes::<400>();
126
127        assert!(values.is_err());
128
129        Ok(())
130    }
131
132    #[test]
133    fn read_n_bytes_dyn() -> error::Result<()> {
134        let mut reader = std::io::Cursor::new(LOREM);
135
136        let values = reader.read_n_bytes_dyn(11)?;
137
138        assert_eq!(&values, b"Lorem ipsum");
139
140        let values = reader.read_n_bytes_dyn(11)?;
141
142        assert_eq!(&values, b" dolor\0sit ");
143
144        let values = reader.read_n_bytes_dyn(400);
145
146        assert!(values.is_err());
147
148        Ok(())
149    }
150
151    #[test]
152    fn read_ascii() -> error::Result<()> {
153        let mut reader = std::io::Cursor::new(LOREM);
154
155        let values = reader.read_ascii()?;
156
157        assert_eq!(&values, b"Lorem ipsum dolor");
158
159        reader.seek(std::io::SeekFrom::Start(values.len() as u64 + 1))?; // Move after first \0
160        let values = reader.read_ascii()?;
161
162        assert_eq!(&values, b"sit amet, consectetur adipiscing elit.");
163
164        reader.seek(std::io::SeekFrom::End(0))?;
165        let values = reader.read_ascii()?;
166
167        assert_eq!(&values, b"");
168
169        Ok(())
170    }
171
172    #[test]
173    fn read_2bits() -> error::Result<()> {
174        let mut reader = std::io::Cursor::new([0b11101110, 0b00010001]);
175
176        let kmer = reader.read_2bits(5)?;
177
178        assert_eq!(
179            kmer,
180            bitvec::bitvec![u8, bitvec::order::Msb0; 1, 1, 1, 0, 1, 1, 1, 0, 0, 0]
181        );
182
183        Ok(())
184    }
185
186    #[test]
187    fn read_bool() -> error::Result<()> {
188        let mut reader = std::io::Cursor::new(LOREM);
189
190        assert!(reader.read_bool()?);
191
192        let _ = reader.read_n_bytes::<16>()?;
193
194        assert!(!reader.read_bool()?);
195
196        Ok(())
197    }
198
199    #[test]
200    fn read_u8() -> error::Result<()> {
201        let mut reader = std::io::Cursor::new(LOREM);
202
203        assert_eq!(reader.read_u8()?, b'L');
204        assert_eq!(reader.read_u8()?, b'o');
205
206        Ok(())
207    }
208
209    #[test]
210    fn read_u16() -> error::Result<()> {
211        let mut reader = std::io::Cursor::new(LOREM);
212
213        assert_eq!(reader.read_u16()?, 19567);
214        assert_eq!(reader.read_u16()?, 29285);
215
216        Ok(())
217    }
218
219    #[test]
220    fn read_u32() -> error::Result<()> {
221        let mut reader = std::io::Cursor::new(LOREM);
222
223        assert_eq!(reader.read_u32()?, 1282372197);
224        assert_eq!(reader.read_u32()?, 1830840688);
225
226        Ok(())
227    }
228
229    #[test]
230    fn read_u64() -> error::Result<()> {
231        let mut reader = std::io::Cursor::new(LOREM);
232
233        assert_eq!(reader.read_u64()?, 5507746649245510000);
234        assert_eq!(reader.read_u64()?, 8319675872528264303);
235
236        Ok(())
237    }
238}