noodles_vcf/header/record/value/map/
builder.rs

1use std::{error, fmt};
2
3use super::{tag, Map, OtherFields};
4
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub enum BuildError {
7    MissingField(&'static str),
8}
9
10impl error::Error for BuildError {}
11
12impl fmt::Display for BuildError {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        match self {
15            Self::MissingField(tag) => write!(f, "missing field: {tag}"),
16        }
17    }
18}
19
20pub trait Inner<I>: Default
21where
22    I: super::Inner,
23{
24    fn build(self) -> Result<I, BuildError>;
25}
26
27pub trait Typed<I>
28where
29    I: super::Typed,
30{
31    fn set_number(self, number: I::Number) -> Self;
32    fn set_type(self, ty: I::Type) -> Self;
33}
34
35pub trait Described<I>
36where
37    I: super::Described,
38{
39    fn set_description<D>(self, description: D) -> Self
40    where
41        D: Into<String>;
42}
43
44pub trait Indexed<I>
45where
46    I: super::Indexed,
47{
48    fn set_idx(self, idx: usize) -> Self;
49}
50
51/// A VCF header record map value builder.
52pub struct Builder<I>
53where
54    I: super::Inner,
55{
56    pub(super) inner: I::Builder,
57    other_fields: OtherFields<I::StandardTag>,
58}
59
60impl<I> Builder<I>
61where
62    I: super::Inner,
63{
64    /// Inserts a key-value pair into the other fields.
65    pub fn insert<V>(mut self, key: tag::Other<I::StandardTag>, value: V) -> Self
66    where
67        V: Into<String>,
68    {
69        self.other_fields.insert(key, value.into());
70        self
71    }
72
73    /// Builds a VCF header record map value.
74    pub fn build(self) -> Result<Map<I>, BuildError> {
75        let inner = self.inner.build()?;
76
77        Ok(Map {
78            inner,
79            other_fields: self.other_fields,
80        })
81    }
82}
83
84impl<I> Builder<I>
85where
86    I: super::Typed,
87    I::Builder: Typed<I>,
88{
89    /// Sets the number.
90    pub fn set_number(mut self, number: I::Number) -> Self {
91        self.inner = self.inner.set_number(number);
92        self
93    }
94
95    /// Sets the type.
96    pub fn set_type(mut self, ty: I::Type) -> Self {
97        self.inner = self.inner.set_type(ty);
98        self
99    }
100}
101
102impl<I> Builder<I>
103where
104    I: super::Described,
105    I::Builder: Described<I>,
106{
107    /// Sets the description.
108    pub fn set_description<D>(mut self, description: D) -> Self
109    where
110        D: Into<String>,
111    {
112        self.inner = self.inner.set_description(description);
113        self
114    }
115}
116
117impl<I> Builder<I>
118where
119    I: super::Indexed,
120    I::Builder: Indexed<I>,
121{
122    /// Sets the index.
123    pub fn set_idx(mut self, idx: usize) -> Self {
124        self.inner = self.inner.set_idx(idx);
125        self
126    }
127}
128
129impl<I> Default for Builder<I>
130where
131    I: super::Inner,
132{
133    fn default() -> Self {
134        Self {
135            inner: I::Builder::default(),
136            other_fields: OtherFields::new(),
137        }
138    }
139}
140
141#[derive(Default)]
142pub struct Identity;
143
144impl<I> Inner<I> for Identity
145where
146    I: Default + super::Inner,
147{
148    fn build(self) -> Result<I, BuildError> {
149        Ok(I::default())
150    }
151}
152
153pub struct TypedDescribedIndexed<I>
154where
155    I: super::Typed + super::Described + super::Indexed,
156{
157    pub(super) number: Option<I::Number>,
158    pub(super) ty: Option<I::Type>,
159    pub(super) description: Option<String>,
160    pub(super) idx: Option<usize>,
161}
162
163impl<I> Typed<I> for TypedDescribedIndexed<I>
164where
165    I: super::Typed + super::Described + super::Indexed,
166{
167    fn set_number(mut self, number: I::Number) -> Self {
168        self.number = Some(number);
169        self
170    }
171
172    fn set_type(mut self, ty: I::Type) -> Self {
173        self.ty = Some(ty);
174        self
175    }
176}
177
178impl<I> Described<I> for TypedDescribedIndexed<I>
179where
180    I: super::Typed + super::Described + super::Indexed,
181{
182    fn set_description<D>(mut self, description: D) -> Self
183    where
184        D: Into<String>,
185    {
186        self.description = Some(description.into());
187        self
188    }
189}
190
191impl<I> Indexed<I> for TypedDescribedIndexed<I>
192where
193    I: super::Typed + super::Described + super::Indexed,
194{
195    fn set_idx(mut self, idx: usize) -> Self {
196        self.idx = Some(idx);
197        self
198    }
199}
200
201impl<I> Default for TypedDescribedIndexed<I>
202where
203    I: super::Typed + super::Described + super::Indexed,
204{
205    fn default() -> Self {
206        Self {
207            number: None,
208            ty: None,
209            description: None,
210            idx: None,
211        }
212    }
213}
214
215#[derive(Default)]
216pub struct DescribedIndexed {
217    pub(super) description: Option<String>,
218    pub(super) idx: Option<usize>,
219}
220
221impl<I> Described<I> for DescribedIndexed
222where
223    I: super::Described,
224{
225    fn set_description<D>(mut self, description: D) -> Self
226    where
227        D: Into<String>,
228    {
229        self.description = Some(description.into());
230        self
231    }
232}
233
234impl<I> Indexed<I> for DescribedIndexed
235where
236    I: super::Indexed,
237{
238    fn set_idx(mut self, idx: usize) -> Self {
239        self.idx = Some(idx);
240        self
241    }
242}