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}