1use crate::primitives::{
2 Action, Annotation, DataType, Link, LocalizedText, Meta, NumberOrString, SdmxMessage,
3 SdmxValue, StatusMessage,
4};
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use std::collections::HashMap;
8use std::str::FromStr;
9
10#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
51pub struct DataMessage {
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub meta: Option<Meta>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub data: Option<Data>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub errors: Option<Vec<StatusMessage>>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 #[serde(flatten)]
60 pub other: Option<HashMap<String, Value>>,
61}
62
63impl SdmxMessage for DataMessage {
64 type Data = Data;
65 fn meta(&self) -> Option<&Meta> {
66 self.meta.as_ref()
67 }
68
69 fn data(&self) -> Option<&Self::Data> {
70 self.data.as_ref()
71 }
72
73 fn errors(&self) -> Option<&Vec<StatusMessage>> {
74 self.errors.as_ref()
75 }
76}
77
78impl<'a> TryFrom<&'a [u8]> for DataMessage {
79 type Error = serde_json::Error;
80 fn try_from(slice: &'a [u8]) -> Result<Self, Self::Error> {
81 serde_json::from_slice(slice)
82 }
83}
84
85impl FromStr for DataMessage {
86 type Err = serde_json::Error;
87 fn from_str(s: &str) -> Result<Self, Self::Err> {
88 serde_json::from_str(s)
89 }
90}
91
92impl TryFrom<Value> for DataMessage {
93 type Error = serde_json::Error;
94 fn try_from(value: Value) -> Result<Self, Self::Error> {
95 serde_json::from_value(value)
96 }
97}
98
99#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
101#[serde(rename_all = "camelCase")]
102pub struct Data {
103 #[serde(skip_serializing_if = "Option::is_none")]
104 pub structures: Option<Vec<Structure>>,
105 #[serde(skip_serializing_if = "Option::is_none")]
106 pub data_sets: Option<Vec<DataSet>>,
107 #[serde(skip_serializing_if = "Option::is_none")]
108 #[serde(flatten)]
109 pub other: Option<HashMap<String, Value>>,
110}
111
112#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
115#[serde(rename_all = "camelCase")]
116pub struct Structure {
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub links: Option<Vec<Link>>,
119 pub dimensions: Dimensions,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub measures: Option<Measures>,
122 pub attributes: Attributes,
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub annotations: Option<Vec<Annotation>>,
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub dataset: Option<DataSet>,
127 #[serde(skip_serializing_if = "Option::is_none")]
128 #[serde(flatten)]
129 pub other: Option<HashMap<String, Value>>,
130}
131
132pub type Dimensions = DimsMeasuresAttributes;
134pub type Measures = DimsMeasuresAttributes;
136pub type Attributes = DimsMeasuresAttributes;
138
139#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
142#[serde(rename_all = "camelCase")]
143pub struct DimsMeasuresAttributes {
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub data_set: Option<Vec<Component>>,
146 #[serde(skip_serializing_if = "Option::is_none")]
147 pub dimension_group: Option<Vec<Component>>,
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub series: Option<Vec<Component>>,
150 #[serde(skip_serializing_if = "Option::is_none")]
151 pub observation: Option<Vec<Component>>,
152 #[serde(skip_serializing_if = "Option::is_none")]
153 #[serde(flatten)]
154 pub other: Option<HashMap<String, Value>>,
155}
156
157#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
159#[serde(rename_all = "camelCase")]
160pub struct Component {
161 pub id: String,
162 #[serde(skip_serializing_if = "Option::is_none")]
163 pub name: Option<String>,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub names: Option<LocalizedText>,
166 pub description: Option<String>,
167 #[serde(skip_serializing_if = "Option::is_none")]
168 pub descriptions: Option<LocalizedText>,
169 pub key_position: Option<usize>,
170 #[serde(skip_serializing_if = "Option::is_none")]
171 pub roles: Option<Vec<String>>,
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub is_mandatory: Option<bool>,
174 pub relationship: Option<AttributeRelationship>,
175 #[serde(skip_serializing_if = "Option::is_none")]
176 pub format: Option<Format>,
177 #[serde(skip_serializing_if = "Option::is_none")]
178 pub default_value: Option<NumberOrString>,
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub links: Option<Vec<Link>>,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 pub annotations: Option<Vec<usize>>,
183 #[serde(skip_serializing_if = "Option::is_none")]
184 pub values: Option<Vec<Option<ComponentValue>>>,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 #[serde(flatten)]
187 pub other: Option<HashMap<String, Value>>,
188}
189
190#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
193#[serde(rename_all = "camelCase")]
194pub struct AttributeRelationship {
195 #[serde(skip_serializing_if = "Option::is_none")]
196 pub dataflow: Option<Value>,
197 #[serde(skip_serializing_if = "Option::is_none")]
198 pub dimensions: Option<Vec<String>>,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 pub observation: Option<Value>,
201 #[serde(skip_serializing_if = "Option::is_none")]
202 pub primary_measure: Option<String>,
203 #[serde(skip_serializing_if = "Option::is_none")]
204 pub measures: Option<Vec<String>>,
205 #[serde(skip_serializing_if = "Option::is_none")]
206 #[serde(flatten)]
207 pub other: Option<HashMap<String, Value>>,
208}
209
210#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
212#[serde(rename_all = "camelCase")]
213pub struct Format {
214 #[serde(skip_serializing_if = "Option::is_none")]
215 pub min_occurs: Option<usize>,
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub max_occurs: Option<usize>,
218 #[serde(skip_serializing_if = "Option::is_none")]
219 pub data_type: Option<DataType>,
220 #[serde(skip_serializing_if = "Option::is_none")]
221 pub is_sequence: Option<bool>,
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub interval: Option<String>,
224 #[serde(skip_serializing_if = "Option::is_none")]
225 pub start_time: Option<String>,
226 #[serde(skip_serializing_if = "Option::is_none")]
227 pub end_time: Option<String>,
228 #[serde(skip_serializing_if = "Option::is_none")]
229 pub min_length: Option<usize>,
230 #[serde(skip_serializing_if = "Option::is_none")]
231 pub max_length: Option<usize>,
232 #[serde(skip_serializing_if = "Option::is_none")]
233 pub min_value: Option<isize>,
234 #[serde(skip_serializing_if = "Option::is_none")]
235 pub max_value: Option<isize>,
236 #[serde(skip_serializing_if = "Option::is_none")]
237 pub decimals: Option<usize>,
238 #[serde(skip_serializing_if = "Option::is_none")]
239 pub is_multilingual: Option<bool>,
240 #[serde(skip_serializing_if = "Option::is_none")]
241 pub sentinel_values: Option<Vec<NumberOrString>>,
242 #[serde(skip_serializing_if = "Option::is_none")]
243 #[serde(flatten)]
244 pub other: Option<HashMap<String, Value>>,
245}
246
247#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
249pub struct ComponentValue {
250 pub id: String,
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub name: Option<String>,
253 #[serde(skip_serializing_if = "Option::is_none")]
254 pub names: Option<LocalizedText>,
255 #[serde(skip_serializing_if = "Option::is_none")]
256 pub values: Option<Vec<SdmxValue>>,
257 pub description: Option<String>,
258 #[serde(skip_serializing_if = "Option::is_none")]
259 pub descriptions: Option<LocalizedText>,
260 #[serde(skip_serializing_if = "Option::is_none")]
261 pub start: Option<String>,
262 #[serde(skip_serializing_if = "Option::is_none")]
263 pub end: Option<String>,
264 #[serde(skip_serializing_if = "Option::is_none")]
265 pub parent: Option<String>,
266 #[serde(skip_serializing_if = "Option::is_none")]
267 pub order: Option<isize>,
268 #[serde(skip_serializing_if = "Option::is_none")]
269 pub links: Option<Vec<Link>>,
270 #[serde(skip_serializing_if = "Option::is_none")]
271 pub annotations: Option<Vec<usize>>,
272 #[serde(skip_serializing_if = "Option::is_none")]
273 #[serde(flatten)]
274 pub other: Option<HashMap<String, Value>>,
275}
276
277#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
281#[serde(rename_all = "camelCase")]
282pub struct DataSet {
283 #[serde(skip_serializing_if = "Option::is_none")]
284 pub structure: Option<isize>,
285 #[serde(skip_serializing_if = "Option::is_none")]
286 pub action: Option<Action>,
287 #[serde(skip_serializing_if = "Option::is_none")]
288 pub reporting_begin: Option<String>,
289 #[serde(skip_serializing_if = "Option::is_none")]
290 pub reporting_end: Option<String>,
291 #[serde(skip_serializing_if = "Option::is_none")]
292 pub valid_from: Option<String>,
293 #[serde(skip_serializing_if = "Option::is_none")]
294 pub valid_to: Option<String>,
295 #[serde(skip_serializing_if = "Option::is_none")]
296 pub publication_year: Option<String>,
297 #[serde(skip_serializing_if = "Option::is_none")]
298 pub publication_period: Option<String>,
299 #[serde(skip_serializing_if = "Option::is_none")]
300 pub links: Option<Vec<Link>>,
301 #[serde(skip_serializing_if = "Option::is_none")]
302 pub annotations: Option<Vec<usize>>,
303 #[serde(skip_serializing_if = "Option::is_none")]
304 pub attributes: Option<Vec<SdmxValue>>,
305 #[serde(skip_serializing_if = "Option::is_none")]
306 pub dimension_group_attributes: Option<HashMap<String, Vec<SdmxValue>>>,
307 #[serde(skip_serializing_if = "Option::is_none")]
308 pub series: Option<HashMap<String, Series>>,
309 #[serde(skip_serializing_if = "Option::is_none")]
310 pub observations: Option<HashMap<String, Vec<SdmxValue>>>,
311 #[serde(skip_serializing_if = "Option::is_none")]
312 #[serde(flatten)]
313 pub other: Option<HashMap<String, Value>>,
314}
315
316#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
318pub struct Series {
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub annotations: Option<Vec<usize>>,
321 #[serde(skip_serializing_if = "Option::is_none")]
322 pub attributes: Option<Vec<SdmxValue>>,
323 #[serde(skip_serializing_if = "Option::is_none")]
324 pub observations: Option<HashMap<String, Vec<SdmxValue>>>,
325 #[serde(skip_serializing_if = "Option::is_none")]
326 #[serde(flatten)]
327 pub other: Option<HashMap<String, Value>>,
328}
329
330impl_extendable!(
331 DataMessage,
332 Data,
333 Structure,
334 DimsMeasuresAttributes,
335 Component,
336 AttributeRelationship,
337 Format,
338 ComponentValue,
339 DataSet,
340 Series,
341);