oca_bundle_semantics/state/
attribute.rs

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