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}