oca_bundle/state/
attribute.rs

1use super::{
2    oca::overlay::unit::{MeasurementSystem, MeasurementUnit},
3    standard::Standard,
4};
5use isolang::Language;
6pub use oca_ast::ast::AttributeType;
7use oca_ast::ast::NestedAttrType;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11use crate::state::{encoding::Encoding, entries::EntriesElement, entry_codes::EntryCodes};
12#[derive(Serialize, Deserialize, Debug, Clone)]
13pub struct Attribute {
14    pub name: String,
15    #[serde(rename = "type")]
16    pub attribute_type: Option<NestedAttrType>,
17    pub is_flagged: bool,
18    pub labels: Option<HashMap<Language, String>>,
19    pub category_labels: Option<HashMap<Language, String>>,
20    pub informations: Option<HashMap<Language, String>>,
21    pub entry_codes: Option<EntryCodes>,
22    pub entries: Option<HashMap<Language, EntriesElement>>,
23    pub mapping: Option<String>,
24    pub encoding: Option<Encoding>,
25    #[cfg(feature = "format_overlay")]
26    pub format: Option<String>,
27    pub units: Option<HashMap<MeasurementSystem, MeasurementUnit>>,
28    pub entry_codes_mapping: Option<Vec<String>>,
29    pub condition: Option<String>,
30    pub dependencies: Option<Vec<String>>,
31    pub cardinality: Option<String>,
32    pub conformance: Option<String>,
33    pub standards: Option<Vec<Standard>>,
34}
35
36impl Default for Attribute {
37    fn default() -> Self {
38        Self::new("".to_string())
39    }
40}
41
42impl Attribute {
43    pub fn new(name: String) -> Attribute {
44        Attribute {
45            name,
46            labels: None,
47            informations: None,
48            category_labels: None,
49            attribute_type: None,
50            is_flagged: false,
51            mapping: None,
52            encoding: None,
53            #[cfg(feature = "format_overlay")]
54            format: None,
55            units: None,
56            entry_codes: None,
57            entries: None,
58            entry_codes_mapping: None,
59            condition: None,
60            dependencies: None,
61            cardinality: None,
62            conformance: None,
63            standards: None,
64        }
65    }
66
67    pub fn set_flagged(&mut self) {
68        self.is_flagged = true;
69    }
70
71    pub fn set_attribute_type(&mut self, attribute_type: NestedAttrType) {
72        self.attribute_type = Some(attribute_type);
73    }
74
75    // Merge assumption is that if `other` is not None then it would overwrite `self` or would be concatenated with `self`
76    pub fn merge(&mut self, other: &Attribute) {
77        if self.name != other.name {
78            panic!("Cannot merge attributes with different names");
79        } else {
80            if other.attribute_type.is_some() {
81                self.attribute_type.clone_from(&other.attribute_type);
82            }
83
84            self.merge_labels(other);
85            self.merge_information(other);
86            self.merge_category_labels(other);
87
88            if other.mapping.is_some() {
89                self.mapping.clone_from(&other.mapping);
90            }
91
92            if other.encoding.is_some() {
93                self.encoding.clone_from(&other.encoding);
94            }
95
96            #[cfg(feature = "format_overlay")]
97            if other.format.is_some() {
98                self.format.clone_from(&other.format);
99            }
100
101            if self.units.is_none() {
102                self.units.clone_from(&other.units);
103            }
104
105            if self.entry_codes.is_none() {
106                self.entry_codes.clone_from(&other.entry_codes);
107            }
108
109            self.merge_entries(other);
110
111            if self.entry_codes_mapping.is_none() {
112                self.entry_codes_mapping.clone_from(&other.entry_codes_mapping);
113            }
114
115            if other.condition.is_some() {
116                self.condition.clone_from(&other.condition);
117
118                if other.dependencies.is_some() {
119                    self.dependencies.clone_from(&other.dependencies);
120                }
121            }
122
123            if other.cardinality.is_some() {
124                self.cardinality.clone_from(&other.cardinality);
125            }
126
127            if other.conformance.is_some() {
128                self.conformance.clone_from(&other.conformance);
129            }
130
131            if other.standards.is_some() {
132                self.standards.clone_from(&other.standards);
133            }
134        }
135    }
136
137    fn merge_entries(&mut self, other: &Attribute) {
138        if self.entries.is_none() {
139            self.entries.clone_from(&other.entries);
140        } else if let Some(entries) = &other.entries {
141            for (lang, entry) in entries {
142                self.entries.as_mut().unwrap().insert(*lang, entry.clone());
143            }
144        }
145    }
146
147    fn merge_category_labels(&mut self, other: &Attribute) {
148        if self.category_labels.is_none() {
149            self.category_labels.clone_from(&other.category_labels);
150        } else if let Some(category_labels) = &other.category_labels {
151            for (lang, category_label) in category_labels {
152                self.category_labels
153                    .as_mut()
154                    .unwrap()
155                    .insert(*lang, category_label.clone());
156            }
157        }
158    }
159    fn merge_information(&mut self, other: &Attribute) {
160        if self.informations.is_none() {
161            self.informations.clone_from(&other.informations);
162        } else if let Some(informations) = &other.informations {
163            for (lang, information) in informations {
164                self.informations
165                    .as_mut()
166                    .unwrap()
167                    .insert(*lang, information.clone());
168            }
169        }
170    }
171    fn merge_labels(&mut self, other: &Attribute) {
172        if self.labels.is_none() {
173            self.labels.clone_from(&other.labels)
174        } else if let Some(labels) = &other.labels {
175            for (lang, label) in labels {
176                self.labels.as_mut().unwrap().insert(*lang, label.clone());
177            }
178        }
179    }
180
181    // pub fn add_mapping(mut self, mapping: String) -> AttributeBuilder {
182    //     self.attribute.mapping = Some(mapping);
183    //     self
184    // }
185
186    // pub fn add_entry_codes_mapping(mut self, mapping: Vec<String>) -> AttributeBuilder {
187    //     self.attribute.entry_codes_mapping = Some(mapping);
188    //     self
189    // }
190}
191
192#[derive(Serialize, Deserialize, Debug, Clone)]
193pub struct Entry {
194    pub id: String,
195    pub translations: HashMap<Language, String>,
196}
197
198impl Entry {
199    pub fn new(id: String, translations: HashMap<Language, String>) -> Entry {
200        Entry { id, translations }
201    }
202}
203
204/*
205#[derive(Serialize, Deserialize, Debug, Clone)]
206pub enum Entries {
207    Sai(HashMap<Language, String>),
208    Object(Vec<Entry>),
209}
210*/