noodles_vcf/variant/record_buf/
builder.rs

1//! VCF record builder.
2
3use noodles_core::Position;
4
5use super::{AlternateBases, Filters, Ids, Info, RecordBuf, Samples};
6
7/// A VCF record builder.
8#[derive(Debug, PartialEq)]
9pub struct Builder {
10    reference_sequence_name: String,
11    variant_start: Option<Position>,
12    ids: Ids,
13    reference_bases: String,
14    alternate_bases: AlternateBases,
15    quality_score: Option<f32>,
16    filters: Filters,
17    info: Info,
18    samples: Samples,
19}
20
21impl Builder {
22    /// Sets the reference sequence name.
23    ///
24    /// # Examples
25    ///
26    /// ```
27    /// use noodles_vcf as vcf;
28    ///
29    /// let record = vcf::variant::RecordBuf::builder()
30    ///     .set_reference_sequence_name("sq0")
31    ///     .build();
32    ///
33    /// assert_eq!(record.reference_sequence_name(), "sq0");
34    /// ```
35    pub fn set_reference_sequence_name<N>(mut self, reference_sequence_name: N) -> Self
36    where
37        N: Into<String>,
38    {
39        self.reference_sequence_name = reference_sequence_name.into();
40        self
41    }
42
43    /// Sets the variant start position.
44    ///
45    /// # Examples
46    ///
47    /// ```
48    /// use noodles_core::Position;
49    /// use noodles_vcf as vcf;
50    ///
51    /// let record = vcf::variant::RecordBuf::builder()
52    ///     .set_variant_start(Position::MIN)
53    ///     .build();
54    ///
55    /// assert_eq!(record.variant_start(), Some(Position::MIN));
56    /// ```
57    pub fn set_variant_start(mut self, position: Position) -> Self {
58        self.variant_start = Some(position);
59        self
60    }
61
62    /// Sets a list of IDs.
63    ///
64    /// # Examples
65    ///
66    /// ```
67    /// use noodles_vcf::{self as vcf, variant::record_buf::Ids};
68    ///
69    /// let ids: Ids = [String::from("nd0")].into_iter().collect();
70    ///
71    /// let record = vcf::variant::RecordBuf::builder()
72    ///     .set_ids(ids.clone())
73    ///     .build();
74    ///
75    /// assert_eq!(record.ids(), &ids);
76    /// ```
77    pub fn set_ids(mut self, ids: Ids) -> Self {
78        self.ids = ids;
79        self
80    }
81
82    /// Sets the reference bases.
83    ///
84    /// # Examples
85    ///
86    /// ```
87    /// use noodles_vcf as vcf;
88    ///
89    /// let record = vcf::variant::RecordBuf::builder()
90    ///     .set_reference_bases("A")
91    ///     .build();
92    ///
93    /// assert_eq!(record.reference_bases(), "A");
94    /// ```
95    pub fn set_reference_bases<B>(mut self, reference_bases: B) -> Self
96    where
97        B: Into<String>,
98    {
99        self.reference_bases = reference_bases.into();
100        self
101    }
102
103    /// Sets the alternate bases.
104    ///
105    /// # Examples
106    ///
107    /// ```
108    /// use noodles_vcf::{self as vcf, variant::record_buf::AlternateBases};
109    ///
110    /// let alternate_bases = AlternateBases::from(vec![String::from("C")]);
111    ///
112    /// let record = vcf::variant::RecordBuf::builder()
113    ///     .set_alternate_bases(alternate_bases.clone())
114    ///     .build();
115    ///
116    /// assert_eq!(record.alternate_bases(), &alternate_bases);
117    /// ```
118    pub fn set_alternate_bases(mut self, alternate_bases: AlternateBases) -> Self {
119        self.alternate_bases = alternate_bases;
120        self
121    }
122
123    /// Sets the quality score.
124    ///
125    /// # Examples
126    ///
127    /// ```
128    /// use noodles_vcf as vcf;
129    ///
130    /// let record = vcf::variant::RecordBuf::builder()
131    ///     .set_quality_score(13.0)
132    ///     .build();
133    ///
134    /// assert_eq!(record.quality_score(), Some(13.0));
135    /// ```
136    pub fn set_quality_score(mut self, quality_score: f32) -> Self {
137        self.quality_score = Some(quality_score);
138        self
139    }
140
141    /// Sets the filters.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use noodles_vcf::{self as vcf, variant::record_buf::Filters};
147    ///
148    /// let record = vcf::variant::RecordBuf::builder()
149    ///     .set_filters(Filters::pass())
150    ///     .build();
151    ///
152    /// assert!(record.filters().is_pass());
153    /// ```
154    pub fn set_filters(mut self, filters: Filters) -> Self {
155        self.filters = filters;
156        self
157    }
158
159    /// Sets additional information.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use noodles_vcf::{
165    ///     self as vcf,
166    ///     variant::{
167    ///         record::info::field::key,
168    ///         record_buf::{info::field::Value, Info},
169    ///     },
170    /// };
171    ///
172    /// let info: Info = [
173    ///     (String::from(key::SAMPLES_WITH_DATA_COUNT), Some(Value::Integer(3))),
174    ///     (String::from(key::ALLELE_FREQUENCIES), Some(Value::from(vec![Some(0.5)]))),
175    /// ]
176    /// .into_iter()
177    /// .collect();
178    ///
179    /// let record = vcf::variant::RecordBuf::builder()
180    ///     .set_info(info.clone())
181    ///     .build();
182    ///
183    /// assert_eq!(record.info(), &info);
184    /// ```
185    pub fn set_info(mut self, info: Info) -> Self {
186        self.info = info;
187        self
188    }
189
190    /// Sets the list of genotypes.
191    ///
192    /// # Examples
193    ///
194    /// ```
195    /// use noodles_vcf::{
196    ///     self as vcf,
197    ///     variant::{
198    ///         record::samples::keys::key,
199    ///         record_buf::{samples::{sample::Value, Keys}, Samples},
200    ///     },
201    /// };
202    ///
203    /// let keys: Keys = [
204    ///     String::from(key::GENOTYPE),
205    ///     String::from(key::CONDITIONAL_GENOTYPE_QUALITY),
206    /// ].into_iter().collect();
207    ///
208    /// let samples = Samples::new(
209    ///     keys,
210    ///     vec![vec![Some(Value::from("0|0")), Some(Value::from(13))]],
211    /// );
212    ///
213    /// let record = vcf::variant::RecordBuf::builder()
214    ///     .set_samples(samples.clone())
215    ///     .build();
216    ///
217    /// assert_eq!(record.samples(), &samples);
218    /// ```
219    pub fn set_samples(mut self, samples: Samples) -> Self {
220        self.samples = samples;
221        self
222    }
223
224    /// Builds a VCF record.
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use noodles_vcf as vcf;
230    /// let record = vcf::variant::RecordBuf::builder().build();
231    /// ```
232    pub fn build(self) -> RecordBuf {
233        RecordBuf {
234            reference_sequence_name: self.reference_sequence_name,
235            variant_start: self.variant_start,
236            ids: self.ids,
237            reference_bases: self.reference_bases,
238            alternate_bases: self.alternate_bases,
239            quality_score: self.quality_score,
240            filters: self.filters,
241            info: self.info,
242            samples: self.samples,
243        }
244    }
245}
246
247impl Default for Builder {
248    fn default() -> Self {
249        Self {
250            reference_sequence_name: String::new(),
251            variant_start: Some(Position::MIN),
252            ids: Ids::default(),
253            reference_bases: String::new(),
254            alternate_bases: AlternateBases::default(),
255            quality_score: None,
256            filters: Filters::default(),
257            info: Info::default(),
258            samples: Samples::default(),
259        }
260    }
261}
262
263#[cfg(test)]
264mod tests {
265    use super::*;
266    use crate::variant::record::AlternateBases as _;
267
268    #[test]
269    fn test_default() {
270        let record = Builder::default();
271
272        assert!(record.reference_sequence_name.is_empty());
273        assert_eq!(record.variant_start, Some(Position::MIN));
274        assert!(record.ids.as_ref().is_empty());
275        assert!(record.reference_bases.is_empty());
276        assert!(record.alternate_bases.is_empty());
277        assert!(record.quality_score.is_none());
278        assert!(record.filters.as_ref().is_empty());
279        assert!(record.info.as_ref().is_empty());
280        assert!(record.samples.is_empty());
281    }
282}