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}