oca_bundle/state/
attribute.rs1use 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 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 }
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