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}