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}