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 MetadataMessage {
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 MetadataMessage {
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 MetadataMessage {
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 MetadataMessage {
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 MetadataMessage {
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 metadata_sets: Option<Vec<MetadataSet>>,
105 #[serde(skip_serializing_if = "Option::is_none")]
106 #[serde(flatten)]
107 pub other: Option<HashMap<String, Value>>,
108}
109
110#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
114#[serde(rename_all = "camelCase")]
115pub struct MetadataSet {
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub action: Option<Action>,
118 #[serde(skip_serializing_if = "Option::is_none")]
119 pub publication_period: Option<String>,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub publication_year: Option<String>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub reporting_begin: Option<String>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub reporting_year: Option<String>,
126 pub id: String,
127 #[serde(rename = "agencyID")]
128 pub agency_id: String,
129 #[serde(skip_serializing_if = "Option::is_none")]
130 pub version: Option<String>,
131 #[serde(skip_serializing_if = "Option::is_none")]
132 pub is_external_reference: Option<bool>,
133 pub metadataflow: Option<String>,
134 pub metadata_provision_agreement: Option<String>,
135 #[serde(skip_serializing_if = "Option::is_none")]
136 pub valid_from: Option<String>,
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub valid_to: Option<String>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub annotations: Option<Vec<Annotation>>,
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub links: Option<Vec<Link>>,
143 pub name: String,
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub names: Option<LocalizedText>,
146 #[serde(skip_serializing_if = "Option::is_none")]
147 pub description: Option<String>,
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub descriptions: Option<LocalizedText>,
150 pub targets: Vec<String>,
151 pub attributes: Vec<Attribute>,
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)]
159pub struct Attribute {
160 pub id: String,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub annotations: Option<Vec<Annotation>>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub format: Option<Format>,
165 pub value: Option<SdmxValue>,
166 pub attributes: Option<Vec<Attribute>>,
167 #[serde(skip_serializing_if = "Option::is_none")]
168 #[serde(flatten)]
169 pub other: Option<HashMap<String, Value>>,
170}
171
172#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
175pub struct Format {
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub data_type: Option<DataType>,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub is_sequence: Option<bool>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub interval: Option<isize>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub start_time: Option<String>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 pub end_time: Option<String>,
186 #[serde(skip_serializing_if = "Option::is_none")]
187 pub min_length: Option<usize>,
188 #[serde(skip_serializing_if = "Option::is_none")]
189 pub max_length: Option<usize>,
190 #[serde(skip_serializing_if = "Option::is_none")]
191 pub min_value: Option<isize>,
192 #[serde(skip_serializing_if = "Option::is_none")]
193 pub max_value: Option<isize>,
194 #[serde(skip_serializing_if = "Option::is_none")]
195 pub decimals: Option<usize>,
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub is_multilingual: Option<bool>,
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub sentinel_values: Option<Vec<NumberOrString>>,
200 #[serde(skip_serializing_if = "Option::is_none")]
201 #[serde(flatten)]
202 pub other: Option<HashMap<String, Value>>,
203}
204
205impl_extendable!(MetadataMessage, Data, MetadataSet, Attribute, Format);