1use crate::error;
9
10pub trait KffRead {
12 fn read_n_bytes<const N: usize>(&mut self) -> error::Result<[u8; N]>;
14
15 fn read_n_bytes_dyn(&mut self, n: usize) -> error::Result<Vec<u8>>;
17
18 fn read_ascii(&mut self) -> error::Result<Vec<u8>>;
20
21 fn read_2bits(
23 &mut self,
24 k: usize,
25 ) -> error::Result<bitvec::vec::BitVec<u8, bitvec::order::Msb0>>;
26
27 fn read_bool(&mut self) -> error::Result<bool> {
29 self.read_u8().map(|x| x != 0)
30 }
31
32 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 fn read_u16(&mut self) -> error::Result<u16> {
40 self.read_n_bytes::<2>().map(u16::from_be_bytes)
41 }
42
43 fn read_u32(&mut self) -> error::Result<u32> {
45 self.read_n_bytes::<4>().map(u32::from_be_bytes)
46 }
47
48 fn read_u64(&mut self) -> error::Result<u64> {
50 self.read_n_bytes::<8>().map(u64::from_be_bytes)
51 }
52
53 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))?; 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}