noodles_sam/io/
writer.rs

1//! SAM writer.
2
3mod builder;
4mod header;
5mod num;
6pub mod record;
7
8use std::io::{self, Write};
9
10pub use self::builder::Builder;
11use self::header::write_header;
12pub(crate) use self::record::write_record;
13use crate::{Header, Record};
14
15/// A SAM writer.
16///
17/// The SAM format is comprised of two parts: 1) a header and 2) a list of records.
18///
19/// Each header line is prefixed with an `@` (at sign). The header is optional and may be empty.
20///
21/// SAM records are line-based and follow directly after the header or the start of the file until
22/// EOF.
23///
24/// # Examples
25///
26/// ```
27/// # use std::io;
28/// use noodles_sam as sam;
29///
30/// let mut writer = sam::io::Writer::new(Vec::new());
31///
32/// let header = sam::Header::builder().add_comment("noodles-sam").build();
33/// writer.write_header(&header)?;
34///
35/// let record = sam::Record::default();
36/// writer.write_record(&header, &record)?;
37///
38/// let expected = b"@CO\tnoodles-sam
39/// *\t4\t*\t0\t255\t*\t*\t0\t0\t*\t*
40/// ";
41///
42/// assert_eq!(&writer.get_ref()[..], &expected[..]);
43/// # Ok::<(), io::Error>(())
44/// ```
45pub struct Writer<W>
46where
47    W: Write,
48{
49    inner: W,
50}
51
52impl<W> Writer<W>
53where
54    W: Write,
55{
56    /// Creates a SAM writer.
57    ///
58    /// # Examples
59    ///
60    /// ```
61    /// use noodles_sam as sam;
62    /// let writer = sam::io::Writer::new(Vec::new());
63    /// ```
64    pub fn new(inner: W) -> Self {
65        Self { inner }
66    }
67
68    /// Returns a reference to the underlying writer.
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// use noodles_sam as sam;
74    /// let writer = sam::io::Writer::new(Vec::new());
75    /// assert!(writer.get_ref().is_empty());
76    /// ```
77    pub fn get_ref(&self) -> &W {
78        &self.inner
79    }
80
81    /// Returns a mutable reference to the underlying writer.
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// use noodles_sam as sam;
87    /// let mut writer = sam::io::Writer::new(Vec::new());
88    /// assert!(writer.get_mut().is_empty());
89    /// ```
90    pub fn get_mut(&mut self) -> &mut W {
91        &mut self.inner
92    }
93
94    /// Returns the underlying writer.
95    ///
96    /// # Examples
97    ///
98    /// ```
99    /// use noodles_sam as sam;
100    /// let writer = sam::io::Writer::new(Vec::new());
101    /// assert!(writer.into_inner().is_empty());
102    /// ```
103    pub fn into_inner(self) -> W {
104        self.inner
105    }
106
107    /// Writes a SAM header.
108    ///
109    /// The SAM header is optional, though recommended to include. A call to this method can be
110    /// omitted if it is empty.
111    ///
112    /// # Examples
113    ///
114    /// ```
115    /// # use std::io;
116    /// use noodles_sam as sam;
117    /// let mut writer = sam::io::Writer::new(Vec::new());
118    /// let header = sam::Header::builder().add_comment("noodles-sam").build();
119    /// writer.write_header(&header)?;
120    /// assert_eq!(writer.get_ref(), b"@CO\tnoodles-sam\n");
121    /// # Ok::<(), io::Error>(())
122    /// ```
123    pub fn write_header(&mut self, header: &Header) -> io::Result<()> {
124        write_header(&mut self.inner, header)
125    }
126
127    /// Writes a SAM record.
128    ///
129    /// # Examples
130    ///
131    /// ```
132    /// # use std::io;
133    /// use noodles_sam as sam;
134    ///
135    /// let mut writer = sam::io::Writer::new(Vec::new());
136    ///
137    /// let header = sam::Header::default();
138    /// let record = sam::Record::default();
139    /// writer.write_record(&header, &record)?;
140    ///
141    /// assert_eq!(writer.get_ref(), b"*\t4\t*\t0\t255\t*\t*\t0\t0\t*\t*\n");
142    /// # Ok::<(), io::Error>(())
143    /// ```
144    pub fn write_record(&mut self, header: &Header, record: &Record) -> io::Result<()> {
145        write_record(&mut self.inner, header, record)
146    }
147}
148
149impl<W> crate::alignment::io::Write for Writer<W>
150where
151    W: Write,
152{
153    fn write_alignment_header(&mut self, header: &Header) -> io::Result<()> {
154        self.write_header(header)
155    }
156
157    fn write_alignment_record(
158        &mut self,
159        header: &Header,
160        record: &dyn crate::alignment::Record,
161    ) -> io::Result<()> {
162        write_record(&mut self.inner, header, record)
163    }
164
165    fn finish(&mut self, _: &Header) -> io::Result<()> {
166        Ok(())
167    }
168}