noodles_fasta/fai/async/io/reader.rs
1use tokio::io::{self, AsyncBufRead};
2
3use crate::fai::Index;
4
5/// An async FASTA index reader.
6pub struct Reader<R> {
7 inner: R,
8}
9
10impl<R> Reader<R>
11where
12 R: AsyncBufRead + Unpin,
13{
14 /// Creates an async FASTA index reader.
15 ///
16 /// # Examples
17 ///
18 /// ```
19 /// use noodles_fasta::fai;
20 /// let data = [];
21 /// let mut reader = fai::r#async::io::Reader::new(&data[..]);
22 /// ```
23 pub fn new(inner: R) -> Self {
24 Self { inner }
25 }
26
27 /// Reads a FASTA index.
28 ///
29 /// The position of the stream is expected to be at the start or at the start of a record.
30 ///
31 /// # Examples
32 ///
33 /// ```
34 /// # use std::io;
35 /// #
36 /// # #[tokio::main]
37 /// # async fn main() -> io::Result<()> {
38 /// use noodles_fasta::fai;
39 ///
40 /// let data = b"sq0\t13\t5\t80\t81\nsq1\t21\t19\t80\t81\n";
41 /// let mut reader = fai::r#async::io::Reader::new(&data[..]);
42 ///
43 /// let index = reader.read_index().await?;
44 ///
45 /// assert_eq!(index, fai::Index::from(vec![
46 /// fai::Record::new(String::from("sq0"), 13, 5, 80, 81),
47 /// fai::Record::new(String::from("sq1"), 21, 19, 80, 81),
48 /// ]));
49 /// # Ok(())
50 /// # }
51 /// ```
52 pub async fn read_index(&mut self) -> io::Result<Index> {
53 use crate::r#async::io::reader::read_line;
54
55 let mut buf = String::new();
56 let mut records = Vec::new();
57
58 loop {
59 buf.clear();
60
61 match read_line(&mut self.inner, &mut buf).await? {
62 0 => break,
63 _ => {
64 let record = buf
65 .parse()
66 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
67
68 records.push(record);
69 }
70 }
71 }
72
73 Ok(Index::from(records))
74 }
75}