phenopacket_builder/v2/
phenopackets.rs

1use crate::{Build, Buildable, Set, Unset};
2use phenopackets::schema::v2::core::{
3    Biosample, Disease, File, Individual, Interpretation, Measurement, MedicalAction, MetaData,
4    PhenotypicFeature,
5};
6use phenopackets::schema::v2::Phenopacket;
7use std::marker::PhantomData;
8
9#[derive(Debug, Default, Clone, PartialEq)]
10pub struct PhenopacketBuilder<T = Unset, U = Unset> {
11    id: Option<String>,
12    subject: Option<Individual>,
13    phenotypic_features: Vec<PhenotypicFeature>,
14    measurements: Vec<Measurement>,
15    biosamples: Vec<Biosample>,
16    interpretations: Vec<Interpretation>,
17    diseases: Vec<Disease>,
18    medical_actions: Vec<MedicalAction>,
19    files: Vec<File>,
20    meta_data: Option<MetaData>,
21    data: PhantomData<(T, U)>,
22}
23
24impl<U> PhenopacketBuilder<Unset, U> {
25    pub fn id(self, id: impl Into<String>) -> PhenopacketBuilder<Set, U> {
26        PhenopacketBuilder {
27            id: Some(id.into()),
28            subject: self.subject,
29            phenotypic_features: self.phenotypic_features,
30            measurements: self.measurements,
31            biosamples: self.biosamples,
32            interpretations: self.interpretations,
33            diseases: self.diseases,
34            medical_actions: self.medical_actions,
35            files: self.files,
36            meta_data: self.meta_data,
37            data: Default::default(),
38        }
39    }
40}
41
42impl<T> PhenopacketBuilder<T, Unset> {
43    pub fn meta_data(self, meta_data: impl Build<MetaData>) -> PhenopacketBuilder<T, Set> {
44        PhenopacketBuilder {
45            id: self.id,
46            subject: self.subject,
47            phenotypic_features: self.phenotypic_features,
48            measurements: self.measurements,
49            biosamples: self.biosamples,
50            interpretations: self.interpretations,
51            diseases: self.diseases,
52            medical_actions: self.medical_actions,
53            files: self.files,
54            meta_data: Some(meta_data.build()),
55            data: Default::default(),
56        }
57    }
58}
59
60impl<T, U> PhenopacketBuilder<T, U> {
61    pub fn subject(mut self, subject: impl Build<Individual>) -> Self {
62        self.subject = Some(subject.build());
63        self
64    }
65
66    pub fn add_phenotypic_feature(
67        mut self,
68        phenotypic_feature: impl Build<PhenotypicFeature>,
69    ) -> Self {
70        self.phenotypic_features.push(phenotypic_feature.build());
71        self
72    }
73
74    pub fn extend_phenotypic_features(
75        mut self,
76        phenotypic_features: impl IntoIterator<Item = impl Build<PhenotypicFeature>>,
77    ) -> Self {
78        self.phenotypic_features
79            .extend(phenotypic_features.into_iter().map(Build::build));
80        self
81    }
82
83    pub fn clear_phenotypic_features(mut self) -> Self {
84        self.phenotypic_features.clear();
85        self
86    }
87
88    // TODO: add the other fields
89}
90
91impl Buildable for Phenopacket {
92    type Builder = PhenopacketBuilder;
93}
94
95impl Build<Phenopacket> for PhenopacketBuilder<Set, Set> {
96    fn build(self) -> Phenopacket {
97        Phenopacket {
98            id: self.id.expect("id must have been set"),
99            subject: self.subject,
100            phenotypic_features: self.phenotypic_features,
101            measurements: self.measurements,
102            biosamples: self.biosamples,
103            interpretations: self.interpretations,
104            diseases: self.diseases,
105            medical_actions: self.medical_actions,
106            files: self.files,
107            meta_data: self.meta_data,
108        }
109    }
110}