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