oca_rust/state/
attribute.rs

1use serde::{Deserialize, Serialize};
2use std::collections::{BTreeMap, HashMap};
3use wasm_bindgen::prelude::*;
4
5use crate::state::{
6    encoding::Encoding, entries::EntriesElement, entry_codes::EntryCodes, language::Language,
7};
8
9#[derive(Serialize, Deserialize)]
10pub struct Attribute {
11    pub name: String,
12    pub attribute_type: AttributeType,
13    pub is_flagged: bool,
14    pub translations: HashMap<Language, AttributeTranslation>,
15    pub mapping: Option<String>,
16    pub encoding: Option<Encoding>,
17    pub format: Option<String>,
18    pub metric_system: Option<String>,
19    pub unit: Option<String>,
20    pub entry_codes: Option<EntryCodes>,
21    pub entry_codes_mapping: Option<Vec<String>>,
22    pub sai: Option<String>,
23    pub condition: Option<String>,
24    pub dependencies: Option<Vec<String>>,
25    pub cardinality: Option<String>,
26    pub conformance: Option<String>,
27}
28
29pub struct AttributeBuilder {
30    pub attribute: Attribute,
31}
32
33impl AttributeBuilder {
34    pub fn new(name: String, attribute_type: AttributeType) -> AttributeBuilder {
35        AttributeBuilder {
36            attribute: Attribute {
37                name,
38                attribute_type,
39                is_flagged: false,
40                translations: HashMap::new(),
41                mapping: None,
42                encoding: None,
43                format: None,
44                metric_system: None,
45                unit: None,
46                entry_codes: None,
47                entry_codes_mapping: None,
48                sai: None,
49                condition: None,
50                dependencies: None,
51                cardinality: None,
52                conformance: None,
53            },
54        }
55    }
56
57    pub fn set_flagged(mut self) -> AttributeBuilder {
58        self.attribute.is_flagged = true;
59        self
60    }
61
62    pub fn add_condition(
63        mut self,
64        condition: String,
65        dependencies: Vec<String>,
66    ) -> AttributeBuilder {
67        self.attribute.condition = Some(condition);
68        self.attribute.dependencies = Some(dependencies);
69        self
70    }
71
72    pub fn add_cardinality(mut self, cardinality: String) -> AttributeBuilder {
73        self.attribute.cardinality = Some(cardinality);
74        self
75    }
76
77    pub fn add_conformance(mut self, conformance: String) -> AttributeBuilder {
78        self.attribute.conformance = Some(conformance);
79        self
80    }
81
82    pub fn add_encoding(mut self, encoding: Encoding) -> AttributeBuilder {
83        self.attribute.encoding = Some(encoding);
84        self
85    }
86
87    pub fn add_mapping(mut self, mapping: String) -> AttributeBuilder {
88        self.attribute.mapping = Some(mapping);
89        self
90    }
91
92    pub fn add_sai(mut self, sai: String) -> AttributeBuilder {
93        self.attribute.sai = Some(sai);
94        self
95    }
96
97    pub fn add_format(mut self, format: String) -> AttributeBuilder {
98        self.attribute.format = Some(format);
99        self
100    }
101
102    pub fn add_unit(mut self, metric_system: String, unit: String) -> AttributeBuilder {
103        self.attribute.metric_system = Some(metric_system);
104        self.attribute.unit = Some(unit);
105        self
106    }
107
108    pub fn add_label(mut self, labels: HashMap<Language, String>) -> AttributeBuilder {
109        for (lang, label) in labels.iter() {
110            match self.attribute.translations.get_mut(lang) {
111                Some(t) => {
112                    t.add_label(label.clone());
113                }
114                None => {
115                    let mut tr = AttributeTranslation::new();
116                    tr.add_label(label.clone());
117                    self.attribute.translations.insert(lang.clone(), tr);
118                }
119            }
120        }
121        self
122    }
123
124    pub fn add_entry_codes(mut self, entry_codes: EntryCodes) -> AttributeBuilder {
125        self.attribute.entry_codes = Some(entry_codes);
126        self
127    }
128
129    pub fn add_entry_codes_mapping(mut self, mapping: Vec<String>) -> AttributeBuilder {
130        self.attribute.entry_codes_mapping = Some(mapping);
131        self
132    }
133
134    pub fn add_entries(mut self, entries: Entries) -> AttributeBuilder {
135        match entries {
136            Entries::Sai(lang_sai) => {
137                for (lang, sai) in lang_sai.iter() {
138                    match self.attribute.translations.get_mut(lang) {
139                        Some(t) => {
140                            t.add_entries_sai(sai.to_string());
141                        }
142                        None => {
143                            let mut tr = AttributeTranslation::new();
144                            tr.add_entries_sai(sai.to_string());
145                            self.attribute.translations.insert(lang.clone(), tr);
146                        }
147                    }
148                }
149            }
150            Entries::Object(entries_vec) => {
151                for entry in entries_vec.iter() {
152                    for (lang, en) in entry.translations.iter() {
153                        match self.attribute.translations.get_mut(lang) {
154                            Some(t) => {
155                                t.add_entry(entry.id.clone(), en.clone());
156                            }
157                            None => {
158                                let mut tr = AttributeTranslation::new();
159                                tr.add_entry(entry.id.clone(), en.clone());
160                                self.attribute.translations.insert(lang.clone(), tr);
161                            }
162                        }
163                    }
164                }
165            }
166        }
167        self
168    }
169
170    pub fn add_information(mut self, information: HashMap<Language, String>) -> AttributeBuilder {
171        for (lang, info) in information.iter() {
172            match self.attribute.translations.get_mut(lang) {
173                Some(t) => {
174                    t.add_information(info.clone());
175                }
176                None => {
177                    let mut tr = AttributeTranslation::new();
178                    tr.add_information(info.clone());
179                    self.attribute.translations.insert(lang.clone(), tr);
180                }
181            }
182        }
183        self
184    }
185
186    pub fn build(self) -> Attribute {
187        self.attribute
188    }
189}
190
191#[derive(Serialize, Deserialize, Debug, Clone)]
192pub struct Entry {
193    pub id: String,
194    pub translations: HashMap<Language, String>,
195}
196
197impl Entry {
198    pub fn new(id: String, translations: HashMap<Language, String>) -> Entry {
199        Entry { id, translations }
200    }
201}
202
203#[derive(Serialize, Deserialize, Debug, Clone)]
204pub enum Entries {
205    Sai(HashMap<Language, String>),
206    Object(Vec<Entry>),
207}
208
209#[derive(Serialize, Deserialize, Debug, Clone)]
210pub struct AttributeTranslation {
211    pub label: Option<String>,
212    pub entries: Option<EntriesElement>,
213    pub information: Option<String>,
214}
215
216impl Default for AttributeTranslation {
217    fn default() -> Self {
218        Self::new()
219    }
220}
221
222impl AttributeTranslation {
223    pub fn new() -> AttributeTranslation {
224        AttributeTranslation {
225            label: None,
226            entries: None,
227            information: None,
228        }
229    }
230
231    pub fn add_label(&mut self, label: String) -> &mut AttributeTranslation {
232        self.label = Some(label);
233        self
234    }
235
236    pub fn add_entries_sai(&mut self, sai: String) -> &mut AttributeTranslation {
237        self.entries = Some(EntriesElement::Sai(sai));
238        self
239    }
240
241    pub fn add_entry(&mut self, id: String, tr: String) -> &mut AttributeTranslation {
242        if self.entries.is_none() {
243            self.entries = Some(EntriesElement::Object(BTreeMap::new()));
244        }
245        if let Some(EntriesElement::Object(mut entries)) = self.entries.clone() {
246            entries.insert(id, tr);
247            self.entries = Some(EntriesElement::Object(entries));
248        }
249        self
250    }
251
252    pub fn add_information(&mut self, information: String) -> &mut AttributeTranslation {
253        self.information = Some(information);
254        self
255    }
256}
257
258#[wasm_bindgen]
259#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
260pub enum AttributeType {
261    Boolean,
262    #[serde(rename = "Array[Boolean]")]
263    ArrayBoolean,
264    Binary,
265    #[serde(rename = "Array[Binary]")]
266    ArrayBinary,
267    Text,
268    #[serde(rename = "Array[Text]")]
269    ArrayText,
270    Numeric,
271    #[serde(rename = "Array[Numeric]")]
272    ArrayNumeric,
273    DateTime,
274    #[serde(rename = "Array[DateTime]")]
275    ArrayDateTime,
276    Reference,
277    #[serde(rename = "Array[Reference]")]
278    ArrayReference,
279}