noodles_fasta/fai/io/
reader.rs

1use std::io::{self, BufRead};
2
3use crate::fai::Index;
4
5/// A FASTA index reader.
6pub struct Reader<R> {
7    inner: R,
8}
9
10impl<R> Reader<R> {
11    /// Returns a reference to the underlying reader.
12    ///
13    /// # Examples
14    ///
15    /// ```
16    /// # use std::io;
17    /// use noodles_fasta::fai;
18    /// let reader = fai::io::Reader::new(io::empty());
19    /// let _inner = reader.get_ref();
20    /// ```
21    pub fn get_ref(&self) -> &R {
22        &self.inner
23    }
24
25    /// Returns a mutable reference to the underlying reader.
26    ///
27    /// # Examples
28    ///
29    /// ```
30    /// # use std::io;
31    /// use noodles_fasta::fai;
32    /// let mut reader = fai::io::Reader::new(io::empty());
33    /// let _inner = reader.get_mut();
34    /// ```
35    pub fn get_mut(&mut self) -> &mut R {
36        &mut self.inner
37    }
38
39    /// Returns the underlying reader.
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// # use std::io;
45    /// use noodles_fasta::fai;
46    /// let reader = fai::io::Reader::new(io::empty());
47    /// let _inner = reader.into_inner();
48    /// ```
49    pub fn into_inner(self) -> R {
50        self.inner
51    }
52}
53
54impl<R> Reader<R>
55where
56    R: BufRead,
57{
58    /// Creates a FASTA index reader.
59    ///
60    /// # Examples
61    ///
62    /// ```
63    /// use noodles_fasta::fai;
64    /// let data = b"sq0\t13\t5\t80\t81\nsq1\t21\t19\t80\t81\n";
65    /// let mut reader = fai::io::Reader::new(&data[..]);
66    /// ```
67    pub fn new(inner: R) -> Self {
68        Self { inner }
69    }
70
71    /// Reads a FASTA index.
72    ///
73    /// The position of the stream is expected to be at the start or at the start of a record.
74    ///
75    /// # Examples
76    ///
77    /// ```
78    /// # use std::io;
79    /// use noodles_fasta::fai;
80    ///
81    /// let data = b"sq0\t13\t5\t80\t81\nsq1\t21\t19\t80\t81\n";
82    /// let mut reader = fai::io::Reader::new(&data[..]);
83    /// let index = reader.read_index()?;
84    ///
85    /// assert_eq!(index, fai::Index::from(vec![
86    ///     fai::Record::new("sq0", 13, 5, 80, 81),
87    ///     fai::Record::new("sq1", 21, 19, 80, 81),
88    /// ]));
89    /// # Ok::<(), io::Error>(())
90    /// ```
91    pub fn read_index(&mut self) -> io::Result<Index> {
92        let mut buf = String::new();
93        let mut records = Vec::new();
94
95        loop {
96            buf.clear();
97
98            match read_line(&mut self.inner, &mut buf) {
99                Ok(0) => break,
100                Ok(_) => {
101                    let record = buf
102                        .parse()
103                        .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
104
105                    records.push(record);
106                }
107                Err(e) => return Err(e),
108            }
109        }
110
111        Ok(Index::from(records))
112    }
113}
114
115pub fn read_line<R>(reader: &mut R, buf: &mut String) -> io::Result<usize>
116where
117    R: BufRead,
118{
119    let result = reader.read_line(buf);
120    buf.pop();
121    result
122}