phenopacket_builder/v2/core/
meta_data.rs

1use crate::{Build, Buildable, Set, Unset};
2use phenopackets::schema::v2::core::{ExternalReference, MetaData, Resource, Update};
3use prost_types::Timestamp;
4use std::marker::PhantomData;
5
6#[derive(Debug, Default, Clone, PartialEq)]
7pub struct MetaDataBuilder<T = Unset, U = Unset, V = Unset> {
8    created: Option<Timestamp>,
9    created_by: Option<String>,
10    submitted_by: Option<String>,
11    resources: Vec<Resource>,
12    updates: Vec<Update>,
13    phenopacket_schema_version: Option<String>,
14    external_references: Vec<ExternalReference>,
15    data: PhantomData<(T, U, V)>,
16}
17
18impl<U, V> MetaDataBuilder<Unset, U, V> {
19    pub fn created(self, created: impl Build<Timestamp>) -> MetaDataBuilder<Set, U, V> {
20        MetaDataBuilder {
21            created: Some(created.build()),
22            created_by: self.created_by,
23            submitted_by: self.submitted_by,
24            resources: self.resources,
25            updates: self.updates,
26            phenopacket_schema_version: self.phenopacket_schema_version,
27            external_references: self.external_references,
28            data: Default::default(),
29        }
30    }
31}
32
33impl<T, V> MetaDataBuilder<T, Unset, V> {
34    pub fn created_by(self, created_by: impl Into<String>) -> MetaDataBuilder<T, Set, V> {
35        MetaDataBuilder {
36            created: self.created,
37            created_by: Some(created_by.into()),
38            submitted_by: self.submitted_by,
39            resources: self.resources,
40            updates: self.updates,
41            phenopacket_schema_version: self.phenopacket_schema_version,
42            external_references: self.external_references,
43            data: Default::default(),
44        }
45    }
46}
47
48impl<T, U> MetaDataBuilder<T, U, Unset> {
49    pub fn phenopacket_schema_version(
50        self,
51        version: impl Into<String>,
52    ) -> MetaDataBuilder<T, U, Set> {
53        MetaDataBuilder {
54            created: self.created,
55            created_by: self.created_by,
56            submitted_by: self.submitted_by,
57            resources: self.resources,
58            updates: self.updates,
59            phenopacket_schema_version: Some(version.into()),
60            external_references: self.external_references,
61            data: Default::default(),
62        }
63    }
64
65    pub fn v2(self) -> MetaDataBuilder<T, U, Set> {
66        self.phenopacket_schema_version("2.0.0")
67    }
68
69    pub fn v2_0_2(self) -> MetaDataBuilder<T, U, Set> {
70        self.phenopacket_schema_version("2.0.2")
71    }
72}
73
74impl<T, U, V> MetaDataBuilder<T, U, V> {
75    pub fn submitted_by(mut self, submitted_by: impl Into<String>) -> Self {
76        self.submitted_by = Some(submitted_by.into());
77        self
78    }
79
80    pub fn add_resource(mut self, resource: impl Build<Resource>) -> Self {
81        self.resources.push(resource.build());
82        self
83    }
84
85    pub fn extend_resources(
86        mut self,
87        resources: impl IntoIterator<Item = impl Build<Resource>>,
88    ) -> Self {
89        self.resources
90            .extend(resources.into_iter().map(Build::build));
91        self
92    }
93
94    pub fn clear_resources(mut self) -> Self {
95        self.resources.clear();
96        self
97    }
98
99    pub fn add_update(mut self, update: impl Build<Update>) -> Self {
100        self.updates.push(update.build());
101        self
102    }
103
104    pub fn extend_updates(mut self, updates: impl IntoIterator<Item = impl Build<Update>>) -> Self {
105        self.updates.extend(updates.into_iter().map(Build::build));
106        self
107    }
108
109    pub fn clear_updates(mut self) -> Self {
110        self.updates.clear();
111        self
112    }
113
114    pub fn add_external_reference(
115        mut self,
116        external_reference: impl Build<ExternalReference>,
117    ) -> Self {
118        self.external_references.push(external_reference.build());
119        self
120    }
121
122    pub fn extend_external_references(
123        mut self,
124        external_references: impl IntoIterator<Item = impl Build<ExternalReference>>,
125    ) -> Self {
126        self.external_references
127            .extend(external_references.into_iter().map(Build::build));
128        self
129    }
130
131    pub fn clear_external_references(mut self) -> Self {
132        self.external_references.clear();
133        self
134    }
135}
136
137impl Buildable for MetaData {
138    type Builder = MetaDataBuilder;
139}
140
141impl Build<MetaData> for MetaDataBuilder<Set, Set, Set> {
142    fn build(self) -> MetaData {
143        MetaData {
144            created: self.created,
145            created_by: self.created_by.expect("created_by must have been set"),
146            submitted_by: self.submitted_by.unwrap_or_default(),
147            resources: self.resources,
148            updates: self.updates,
149            phenopacket_schema_version: self
150                .phenopacket_schema_version
151                .expect("phenopacket schema must have been set"),
152            external_references: self.external_references,
153        }
154    }
155}
156
157#[derive(Debug, Default, Clone, PartialEq)]
158pub struct ResourceBuilder<T = Unset, U = Unset, V = Unset, X = Unset, Y = Unset, Z = Unset> {
159    id: Option<String>,
160    name: Option<String>,
161    namespace_prefix: Option<String>,
162    url: Option<String>,
163    version: Option<String>,
164    iri_prefix: Option<String>,
165    data: PhantomData<(T, U, V, X, Y, Z)>,
166}
167
168impl<U, V, X, Y, Z> ResourceBuilder<Unset, U, V, X, Y, Z> {
169    pub fn id(self, id: impl Into<String>) -> ResourceBuilder<Set, U, V, X, Y, Z> {
170        ResourceBuilder {
171            id: Some(id.into()),
172            name: self.name,
173            namespace_prefix: self.namespace_prefix,
174            url: self.url,
175            version: self.version,
176            iri_prefix: self.iri_prefix,
177            data: Default::default(),
178        }
179    }
180}
181
182impl<T, V, X, Y, Z> ResourceBuilder<T, Unset, V, X, Y, Z> {
183    pub fn name(self, name: impl Into<String>) -> ResourceBuilder<T, Set, V, X, Y, Z> {
184        ResourceBuilder {
185            id: self.id,
186            name: Some(name.into()),
187            namespace_prefix: self.namespace_prefix,
188            url: self.url,
189            version: self.version,
190            iri_prefix: self.iri_prefix,
191            data: Default::default(),
192        }
193    }
194}
195
196impl<T, U, X, Y, Z> ResourceBuilder<T, U, Unset, X, Y, Z> {
197    pub fn namespace_prefix(
198        self,
199        namespace_prefix: impl Into<String>,
200    ) -> ResourceBuilder<T, U, Set, X, Y, Z> {
201        ResourceBuilder {
202            id: self.id,
203            name: self.name,
204            namespace_prefix: Some(namespace_prefix.into()),
205            url: self.url,
206            version: self.version,
207            iri_prefix: self.iri_prefix,
208            data: Default::default(),
209        }
210    }
211}
212
213impl<T, U, V, Y, Z> ResourceBuilder<T, U, V, Unset, Y, Z> {
214    pub fn url(self, url: impl Into<String>) -> ResourceBuilder<T, U, V, Set, Y, Z> {
215        ResourceBuilder {
216            id: self.id,
217            name: self.name,
218            namespace_prefix: self.namespace_prefix,
219            url: Some(url.into()),
220            version: self.version,
221            iri_prefix: self.iri_prefix,
222            data: Default::default(),
223        }
224    }
225}
226
227impl<T, U, V, X, Z> ResourceBuilder<T, U, V, X, Unset, Z> {
228    pub fn version(self, version: impl Into<String>) -> ResourceBuilder<T, U, V, X, Set, Z> {
229        ResourceBuilder {
230            id: self.id,
231            name: self.name,
232            namespace_prefix: self.namespace_prefix,
233            url: self.url,
234            version: Some(version.into()),
235            iri_prefix: self.iri_prefix,
236            data: Default::default(),
237        }
238    }
239}
240
241impl<T, U, V, X, Y> ResourceBuilder<T, U, V, X, Y, Unset> {
242    pub fn iri_prefix(self, iri_prefix: impl Into<String>) -> ResourceBuilder<T, U, V, X, Y, Set> {
243        ResourceBuilder {
244            id: self.id,
245            name: self.name,
246            namespace_prefix: self.namespace_prefix,
247            url: self.url,
248            version: self.version,
249            iri_prefix: Some(iri_prefix.into()),
250            data: Default::default(),
251        }
252    }
253}
254
255impl<T, U, V, X, Y, Z> ResourceBuilder<T, U, V, X, Y, Z> {
256    pub fn hpo(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
257        ResourceBuilder {
258            id: Some("hp".into()),
259            name: Some("human phenotype ontology".into()),
260            namespace_prefix: Some("HP".into()),
261            url: Some("https://purl.obolibrary.org/obo/hp.owl".into()),
262            version: Some(version.into()),
263            iri_prefix: Some("https://purl.obolibrary.org/obo/HP_".into()),
264            data: Default::default(),
265        }
266    }
267
268    pub fn geno(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
269        ResourceBuilder {
270            id: Some("geno".into()),
271            name: Some("genotype ontology".into()),
272            namespace_prefix: Some("GENO".into()),
273            url: Some("https://purl.obolibrary.org/obo/geno.owl".into()),
274            version: Some(version.into()),
275            iri_prefix: Some("https://purl.obolibrary.org/obo/GENO_".into()),
276            data: Default::default(),
277        }
278    }
279
280    pub fn ncit(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
281        ResourceBuilder {
282            id: Some("ncit".into()),
283            name: Some("NCI Thesaurus".into()),
284            namespace_prefix: Some("NCIT".into()),
285            url: Some("https://purl.obolibrary.org/obo/geno.owl".into()),
286            version: Some(version.into()),
287            iri_prefix: Some("https://purl.obolibrary.org/obo/NCIT_".into()),
288            data: Default::default(),
289        }
290    }
291
292    pub fn mondo(
293        self,
294        version: impl Into<String>,
295    ) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
296        ResourceBuilder {
297            id: Some("mondo".into()),
298            name: Some("Mondo Disease Ontology".into()),
299            namespace_prefix: Some("MONDO".into()),
300            url: Some("https://purl.obolibrary.org/obo/mondo.obo".into()),
301            version: Some(version.into()),
302            iri_prefix: Some("https://purl.obolibrary.org/obo/MONDO_".into()),
303            data: Default::default(),
304        }
305    }
306
307    pub fn uberon(
308        self,
309        version: impl Into<String>,
310    ) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
311        ResourceBuilder {
312            id: Some("uberon".into()),
313            name: Some("Uber-anatomy ontology".into()),
314            namespace_prefix: Some("UBERON".into()),
315            url: Some("https://purl.obolibrary.org/obo/uberon.owl".into()),
316            version: Some(version.into()),
317            iri_prefix: Some("https://purl.obolibrary.org/obo/UBERON_".into()),
318            data: Default::default(),
319        }
320    }
321
322    pub fn ncbi_taxon(
323        self,
324        version: impl Into<String>,
325    ) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
326        ResourceBuilder {
327            id: Some("ncbitaxon".into()),
328            name: Some("NCBI organismal classification".into()),
329            namespace_prefix: Some("NCBITaxon".into()),
330            url: Some("https://purl.obolibrary.org/obo/ncbitaxon.owl".into()),
331            version: Some(version.into()),
332            iri_prefix: Some("https://purl.obolibrary.org/obo/NCBITaxon_".into()),
333            data: Default::default(),
334        }
335    }
336
337    pub fn so(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
338        ResourceBuilder {
339            id: Some("so".into()),
340            name: Some("Sequence types and features ontology".into()),
341            namespace_prefix: Some("SO".into()),
342            url: Some("https://purl.obolibrary.org/obo/so.owl".into()),
343            version: Some(version.into()),
344            iri_prefix: Some("https://purl.obolibrary.org/obo/SO_".into()),
345            data: Default::default(),
346        }
347    }
348
349    pub fn ucum(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
350        ResourceBuilder {
351            id: Some("ucum".into()),
352            name: Some("Unified Code for Units of Measure".into()),
353            namespace_prefix: Some("UCUM".into()),
354            url: Some("https://ucum.org".into()),
355            version: Some(version.into()),
356            iri_prefix: Some("https://units-of-measurement.org/".into()),
357            data: Default::default(),
358        }
359    }
360
361    pub fn uo(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
362        ResourceBuilder {
363            id: Some("uo".into()),
364            name: Some("Units of measurement ontology".into()),
365            namespace_prefix: Some("UO".into()),
366            url: Some("https://purl.obolibrary.org/obo/uo.owl".into()),
367            version: Some(version.into()),
368            iri_prefix: Some("https://purl.obolibrary.org/obo/UO_".into()),
369            data: Default::default(),
370        }
371    }
372
373    pub fn loinc(
374        self,
375        version: impl Into<String>,
376    ) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
377        ResourceBuilder {
378            id: Some("loinc".into()),
379            name: Some("Logical Observation Identifiers Names and Codes".into()),
380            namespace_prefix: Some("LOINC".into()),
381            url: Some("https://loinc.org".into()),
382            version: Some(version.into()),
383            iri_prefix: Some("https://loinc.org/".into()),
384            data: Default::default(),
385        }
386    }
387
388    pub fn omim(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
389        ResourceBuilder {
390            id: Some("omim".into()),
391            name: Some("An Online Catalog of Human Genes and Genetic Disorders".into()),
392            namespace_prefix: Some("OMIM".into()),
393            url: Some("https://www.omim.org".into()),
394            version: Some(version.into()),
395            iri_prefix: Some("https://www.omim.org/entry/".into()),
396            data: Default::default(),
397        }
398    }
399
400    pub fn hgnc(self, version: impl Into<String>) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
401        ResourceBuilder {
402            id: Some("hgnc".into()),
403            name: Some("HUGO Gene Nomenclature Committee".into()),
404            namespace_prefix: Some("HGNC".into()),
405            url: Some("https://www.genenames.org".into()),
406            version: Some(version.into()),
407            iri_prefix: Some(
408                "https://www.genenames.org/data/gene-symbol-report/#!/hgnc_id/".into(),
409            ),
410            data: Default::default(),
411        }
412    }
413
414    pub fn pmid(self) -> ResourceBuilder<Set, Set, Set, Set, Set, Set> {
415        ResourceBuilder {
416            id: Some("pmid".into()),
417            name: Some("PubMed".into()),
418            namespace_prefix: Some("PMID".into()),
419            url: Some("https://pubmed.ncbi.nlm.nih.gov".into()),
420            version: Some("".into()),
421            iri_prefix: Some("https://pubmed.ncbi.nlm.nih.gov/".into()),
422            data: Default::default(),
423        }
424    }
425}
426
427impl Buildable for Resource {
428    type Builder = ResourceBuilder;
429}
430
431impl Build<Resource> for ResourceBuilder<Set, Set, Set, Set, Set, Set> {
432    fn build(self) -> Resource {
433        Resource {
434            id: self.id.expect("id must have been set"),
435            name: self.name.expect("name must have been set"),
436            url: self.url.expect("url must have been set"),
437            version: self.version.expect("version must have been set"),
438            namespace_prefix: self
439                .namespace_prefix
440                .expect("namespace prefix must have been set"),
441            iri_prefix: self.iri_prefix.expect("iri prefix must have been set"),
442        }
443    }
444}
445
446#[derive(Debug, Default, Clone, PartialEq)]
447pub struct UpdateBuilder<T = Unset> {
448    timestamp: Option<Timestamp>,
449    updated_by: Option<String>,
450    comment: Option<String>,
451
452    data: PhantomData<T>,
453}
454
455impl UpdateBuilder<Unset> {
456    pub fn timestamp(self, timestamp: impl Build<Timestamp>) -> UpdateBuilder<Set> {
457        UpdateBuilder {
458            timestamp: Some(timestamp.build()),
459            updated_by: self.updated_by,
460            comment: self.comment,
461            data: Default::default(),
462        }
463    }
464}
465
466impl<T> UpdateBuilder<T> {
467    pub fn updated_by(self, updated_by: impl Into<String>) -> UpdateBuilder<T> {
468        UpdateBuilder {
469            timestamp: self.timestamp,
470            updated_by: Some(updated_by.into()),
471            comment: self.comment,
472            data: Default::default(),
473        }
474    }
475
476    pub fn comment(self, comment: impl Into<String>) -> UpdateBuilder<T> {
477        UpdateBuilder {
478            timestamp: self.timestamp,
479            updated_by: self.updated_by,
480            comment: Some(comment.into()),
481            data: Default::default(),
482        }
483    }
484}
485
486impl Buildable for Update {
487    type Builder = UpdateBuilder;
488}
489
490impl Build<Update> for UpdateBuilder<Set> {
491    fn build(self) -> Update {
492        Update {
493            timestamp: self.timestamp,
494            updated_by: self.updated_by.unwrap_or_default(),
495            comment: self.comment.unwrap_or_default(),
496        }
497    }
498}