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}