noodles_sam/alignment/record_buf/builder.rs
1use bstr::BString;
2use noodles_core::Position;
3
4use super::{Cigar, Data, Flags, MappingQuality, QualityScores, RecordBuf, Sequence};
5
6/// An alignment record builder.
7#[derive(Debug)]
8pub struct Builder {
9 name: Option<BString>,
10 flags: Flags,
11 reference_sequence_id: Option<usize>,
12 alignment_start: Option<Position>,
13 mapping_quality: Option<MappingQuality>,
14 cigar: Cigar,
15 mate_reference_sequence_id: Option<usize>,
16 mate_alignment_start: Option<Position>,
17 template_length: i32,
18 sequence: Sequence,
19 quality_scores: QualityScores,
20 data: Data,
21}
22
23impl Builder {
24 /// Sets the read name.
25 ///
26 /// # Examples
27 ///
28 /// ```
29 /// use bstr::ByteSlice;
30 /// use noodles_sam as sam;
31 ///
32 /// let record = sam::alignment::RecordBuf::builder()
33 /// .set_name("r1")
34 /// .build();
35 ///
36 /// assert_eq!(record.name(), Some(b"r1".as_bstr()));
37 /// ```
38 pub fn set_name<N>(mut self, name: N) -> Self
39 where
40 N: Into<BString>,
41 {
42 self.name = Some(name.into());
43 self
44 }
45
46 /// Sets the flags.
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// use noodles_sam::{self as sam, alignment::record::Flags};
52 ///
53 /// let record = sam::alignment::RecordBuf::builder()
54 /// .set_flags(Flags::empty())
55 /// .build();
56 ///
57 /// assert_eq!(record.flags(), Flags::empty());
58 /// ```
59 pub fn set_flags(mut self, flags: Flags) -> Self {
60 self.flags = flags;
61 self
62 }
63
64 /// Sets the reference sequence ID.
65 ///
66 /// # Examples
67 ///
68 /// ```
69 /// use noodles_sam as sam;
70 ///
71 /// let record = sam::alignment::RecordBuf::builder()
72 /// .set_reference_sequence_id(0)
73 /// .build();
74 ///
75 /// assert_eq!(record.reference_sequence_id(), Some(0));
76 /// ```
77 pub fn set_reference_sequence_id(mut self, reference_sequence_id: usize) -> Self {
78 self.reference_sequence_id = Some(reference_sequence_id);
79 self
80 }
81
82 /// Sets the alignment start.
83 ///
84 /// # Examples
85 ///
86 /// ```
87 /// use noodles_core::Position;
88 /// use noodles_sam as sam;
89 ///
90 /// let record = sam::alignment::RecordBuf::builder()
91 /// .set_alignment_start(Position::MIN)
92 /// .build();
93 ///
94 /// assert_eq!(record.alignment_start(), Some(Position::MIN));
95 /// ```
96 pub fn set_alignment_start(mut self, alignment_start: Position) -> Self {
97 self.alignment_start = Some(alignment_start);
98 self
99 }
100
101 /// Sets the mapping quality.
102 ///
103 /// # Examples
104 ///
105 /// ```
106 /// use noodles_sam::{self as sam, alignment::record::MappingQuality};
107 ///
108 /// let record = sam::alignment::RecordBuf::builder()
109 /// .set_mapping_quality(MappingQuality::MIN)
110 /// .build();
111 ///
112 /// assert_eq!(record.mapping_quality(), Some(MappingQuality::MIN));
113 /// ```
114 pub fn set_mapping_quality(mut self, mapping_quality: MappingQuality) -> Self {
115 self.mapping_quality = Some(mapping_quality);
116 self
117 }
118
119 /// Sets the CIGAR operations.
120 ///
121 /// # Examples
122 ///
123 /// ```
124 /// use noodles_sam::{
125 /// self as sam,
126 /// alignment::{
127 /// record::cigar::{op::Kind, Op},
128 /// record_buf::Cigar,
129 /// },
130 /// };
131 ///
132 /// let cigar: Cigar = [Op::new(Kind::Match, 4)].into_iter().collect();
133 ///
134 /// let record = sam::alignment::RecordBuf::builder()
135 /// .set_cigar(cigar.clone())
136 /// .build();
137 ///
138 /// assert_eq!(record.cigar(), &cigar);
139 /// ```
140 pub fn set_cigar(mut self, cigar: Cigar) -> Self {
141 self.cigar = cigar;
142 self
143 }
144
145 /// Sets the mate reference sequence ID.
146 ///
147 /// # Examples
148 ///
149 /// ```
150 /// use noodles_sam as sam;
151 ///
152 /// let record = sam::alignment::RecordBuf::builder()
153 /// .set_mate_reference_sequence_id(0)
154 /// .build();
155 ///
156 /// assert_eq!(record.mate_reference_sequence_id(), Some(0));
157 /// ```
158 pub fn set_mate_reference_sequence_id(mut self, mate_reference_sequence_id: usize) -> Self {
159 self.mate_reference_sequence_id = Some(mate_reference_sequence_id);
160 self
161 }
162
163 /// Sets the mate alignment start.
164 ///
165 /// # Examples
166 ///
167 /// ```
168 /// use noodles_core::Position;
169 /// use noodles_sam as sam;
170 ///
171 /// let record = sam::alignment::RecordBuf::builder()
172 /// .set_mate_alignment_start(Position::MIN)
173 /// .build();
174 ///
175 /// assert_eq!(record.mate_alignment_start(), Some(Position::MIN));
176 /// ```
177 pub fn set_mate_alignment_start(mut self, mate_alignment_start: Position) -> Self {
178 self.mate_alignment_start = Some(mate_alignment_start);
179 self
180 }
181
182 /// Sets the template length.
183 ///
184 /// # Examples
185 ///
186 /// ```
187 /// use noodles_sam as sam;
188 ///
189 /// let record = sam::alignment::RecordBuf::builder()
190 /// .set_template_length(4)
191 /// .build();
192 ///
193 /// assert_eq!(record.template_length(), 4);
194 /// ```
195 pub fn set_template_length(mut self, template_length: i32) -> Self {
196 self.template_length = template_length;
197 self
198 }
199
200 /// Sets the sequence.
201 ///
202 /// # Examples
203 ///
204 /// ```
205 /// use noodles_sam::{self as sam, alignment::record_buf::Sequence};
206 ///
207 /// let sequence = Sequence::from(b"ACGT");
208 ///
209 /// let record = sam::alignment::RecordBuf::builder()
210 /// .set_sequence(sequence.clone())
211 /// .build();
212 ///
213 /// assert_eq!(record.sequence(), &sequence);
214 /// ```
215 pub fn set_sequence(mut self, sequence: Sequence) -> Self {
216 self.sequence = sequence;
217 self
218 }
219
220 /// Sets the quality scores.
221 ///
222 /// # Examples
223 ///
224 /// ```
225 /// use noodles_sam::{self as sam, alignment::record_buf::QualityScores};
226 ///
227 /// let quality_scores = QualityScores::from(vec![45, 35, 43, 50]);
228 ///
229 /// let record = sam::alignment::RecordBuf::builder()
230 /// .set_quality_scores(quality_scores.clone())
231 /// .build();
232 ///
233 /// assert_eq!(record.quality_scores(), &quality_scores);
234 /// ```
235 pub fn set_quality_scores(mut self, quality_scores: QualityScores) -> Self {
236 self.quality_scores = quality_scores;
237 self
238 }
239
240 /// Sets the data.
241 ///
242 /// # Examples
243 ///
244 /// ```
245 /// use noodles_sam::{
246 /// self as sam,
247 /// alignment::{
248 /// record::data::field::Tag,
249 /// record_buf::{data::field::Value, Data},
250 /// },
251 /// };
252 ///
253 /// let data: Data = [(Tag::ALIGNMENT_HIT_COUNT, Value::from(1))]
254 /// .into_iter()
255 /// .collect();
256 ///
257 /// let record = sam::alignment::RecordBuf::builder()
258 /// .set_data(data.clone())
259 /// .build();
260 ///
261 /// assert_eq!(record.data(), &data);
262 /// ```
263 pub fn set_data(mut self, data: Data) -> Self {
264 self.data = data;
265 self
266 }
267
268 /// Builds the alignment record.
269 ///
270 /// # Examples
271 ///
272 /// ```
273 /// use noodles_sam as sam;
274 /// let record = sam::alignment::RecordBuf::builder().build();
275 /// assert_eq!(record, sam::alignment::RecordBuf::default());
276 /// ```
277 pub fn build(self) -> RecordBuf {
278 RecordBuf {
279 name: self.name,
280 flags: self.flags,
281 reference_sequence_id: self.reference_sequence_id,
282 alignment_start: self.alignment_start,
283 mapping_quality: self.mapping_quality,
284 cigar: self.cigar,
285 mate_reference_sequence_id: self.mate_reference_sequence_id,
286 mate_alignment_start: self.mate_alignment_start,
287 template_length: self.template_length,
288 sequence: self.sequence,
289 quality_scores: self.quality_scores,
290 data: self.data,
291 }
292 }
293}
294
295impl Default for Builder {
296 fn default() -> Self {
297 Self {
298 name: None,
299 flags: Flags::UNMAPPED,
300 reference_sequence_id: None,
301 alignment_start: None,
302 mapping_quality: None,
303 cigar: Cigar::default(),
304 mate_reference_sequence_id: None,
305 mate_alignment_start: None,
306 template_length: 0,
307 sequence: Sequence::default(),
308 quality_scores: QualityScores::default(),
309 data: Data::default(),
310 }
311 }
312}
313
314#[cfg(test)]
315mod tests {
316 use super::*;
317
318 #[test]
319 fn test_default() {
320 let builder = Builder::default();
321
322 assert!(builder.name.is_none());
323 assert_eq!(builder.flags, Flags::UNMAPPED);
324 assert!(builder.reference_sequence_id.is_none());
325 assert!(builder.alignment_start.is_none());
326 assert!(builder.mapping_quality.is_none());
327 assert!(builder.cigar.as_ref().is_empty());
328 assert!(builder.mate_reference_sequence_id.is_none());
329 assert!(builder.mate_alignment_start.is_none());
330 assert_eq!(builder.template_length, 0);
331 assert!(builder.sequence.is_empty());
332 assert!(builder.quality_scores.is_empty());
333 assert!(builder.data.is_empty());
334 }
335}