Skip to main content

cbr_client/
query.rs

1use serde::Serialize;
2use serde::ser::{SerializeMap, SerializeSeq, Serializer};
3
4use crate::types::{CategoryId, DatasetId, IndicatorId, MeasureId, PublicationId, Year, YearSpan};
5
6#[derive(Debug, Clone, Copy)]
7struct YearsRangeQuery {
8    span: YearSpan,
9}
10
11impl YearsRangeQuery {
12    #[inline]
13    fn from_span(span: YearSpan) -> Self {
14        Self { span }
15    }
16
17    #[inline]
18    fn span(self) -> YearSpan {
19        self.span
20    }
21
22    #[inline]
23    fn start(self) -> Year {
24        self.span.start()
25    }
26
27    #[inline]
28    fn end(self) -> Year {
29        self.span.end()
30    }
31}
32
33impl Serialize for YearsRangeQuery {
34    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
35    where
36        S: Serializer,
37    {
38        let mut map = serializer.serialize_map(Some(2))?;
39        map.serialize_entry("y1", &self.start())?;
40        map.serialize_entry("y2", &self.end())?;
41        map.end()
42    }
43}
44
45/// Параметры для метода `/data`.
46#[derive(Debug, Clone)]
47pub struct DataQuery {
48    years: YearsRangeQuery,
49    dataset_id: DatasetId,
50    publication_id: PublicationId,
51    measure_id: Option<MeasureId>,
52}
53
54impl DataQuery {
55    /// Создаёт запрос с обязательными полями.
56    #[must_use]
57    #[inline]
58    pub fn new(years: YearSpan, dataset_id: DatasetId, publication_id: PublicationId) -> Self {
59        Self {
60            years: YearsRangeQuery::from_span(years),
61            dataset_id,
62            publication_id,
63            measure_id: None,
64        }
65    }
66
67    /// Добавляет параметр `measureId`.
68    #[must_use]
69    #[inline]
70    pub fn with_measure_id(mut self, measure_id: MeasureId) -> Self {
71        self.measure_id = Some(measure_id);
72        self
73    }
74
75    /// Возвращает диапазон годов запроса.
76    #[must_use]
77    #[inline]
78    pub fn years(&self) -> YearSpan {
79        self.years.span()
80    }
81
82    /// Возвращает идентификатор показателя.
83    #[must_use]
84    #[inline]
85    pub fn dataset_id(&self) -> DatasetId {
86        self.dataset_id
87    }
88
89    /// Возвращает идентификатор публикации.
90    #[must_use]
91    #[inline]
92    pub fn publication_id(&self) -> PublicationId {
93        self.publication_id
94    }
95
96    /// Возвращает идентификатор разреза, если задан.
97    #[must_use]
98    #[inline]
99    pub fn measure_id(&self) -> Option<MeasureId> {
100        self.measure_id
101    }
102}
103
104impl Serialize for DataQuery {
105    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
106    where
107        S: Serializer,
108    {
109        let fields = if self.measure_id.is_some() { 5 } else { 4 };
110        let mut map = serializer.serialize_map(Some(fields))?;
111        map.serialize_entry("y1", &self.years.start())?;
112        map.serialize_entry("y2", &self.years.end())?;
113        map.serialize_entry("datasetId", &self.dataset_id)?;
114        map.serialize_entry("publicationId", &self.publication_id)?;
115
116        if let Some(measure_id) = self.measure_id {
117            map.serialize_entry("measureId", &measure_id)?;
118        }
119
120        map.end()
121    }
122}
123
124/// Параметры для метода `/dataEx`.
125#[derive(Debug, Clone)]
126pub struct DataExQuery {
127    inner: MultiIdsQuery<PublicationId>,
128}
129
130impl DataExQuery {
131    /// Создаёт запрос с обязательными полями.
132    #[must_use]
133    #[inline]
134    pub fn new(publication_id: PublicationId, years: YearSpan) -> Self {
135        Self {
136            inner: MultiIdsQuery::new(publication_id, years),
137        }
138    }
139
140    /// Устанавливает массив `i_ids`.
141    #[must_use]
142    #[inline]
143    pub fn with_i_ids<I>(mut self, ids: I) -> Self
144    where
145        I: IntoIterator<Item = IndicatorId>,
146    {
147        self.inner = self.inner.with_i_ids(ids);
148        self
149    }
150
151    /// Устанавливает массив `m1_ids`.
152    #[must_use]
153    #[inline]
154    pub fn with_m1_ids<I>(mut self, ids: I) -> Self
155    where
156        I: IntoIterator<Item = MeasureId>,
157    {
158        self.inner = self.inner.with_m1_ids(ids);
159        self
160    }
161
162    /// Устанавливает массив `m2_ids`.
163    #[must_use]
164    #[inline]
165    pub fn with_m2_ids<I>(mut self, ids: I) -> Self
166    where
167        I: IntoIterator<Item = MeasureId>,
168    {
169        self.inner = self.inner.with_m2_ids(ids);
170        self
171    }
172
173    /// Возвращает идентификатор публикации.
174    #[must_use]
175    #[inline]
176    pub fn publication_id(&self) -> PublicationId {
177        self.inner.root_id()
178    }
179
180    /// Возвращает диапазон годов.
181    #[must_use]
182    #[inline]
183    pub fn years(&self) -> YearSpan {
184        self.inner.years()
185    }
186
187    /// Возвращает фильтр `i_ids`.
188    #[must_use]
189    #[inline]
190    pub fn i_ids(&self) -> &[IndicatorId] {
191        self.inner.i_ids()
192    }
193
194    /// Возвращает фильтр `m1_ids`.
195    #[must_use]
196    #[inline]
197    pub fn m1_ids(&self) -> &[MeasureId] {
198        self.inner.m1_ids()
199    }
200
201    /// Возвращает фильтр `m2_ids`.
202    #[must_use]
203    #[inline]
204    pub fn m2_ids(&self) -> &[MeasureId] {
205        self.inner.m2_ids()
206    }
207}
208
209impl Serialize for DataExQuery {
210    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
211    where
212        S: Serializer,
213    {
214        serialize_multi_ids_query(serializer, "publicationId", &self.inner)
215    }
216}
217
218/// Параметры для метода `/dataNew`.
219#[derive(Debug, Clone)]
220pub struct DataNewQuery {
221    inner: MultiIdsQuery<CategoryId>,
222}
223
224impl DataNewQuery {
225    /// Создаёт запрос с обязательными полями.
226    #[must_use]
227    #[inline]
228    pub fn new(category_id: CategoryId, years: YearSpan) -> Self {
229        Self {
230            inner: MultiIdsQuery::new(category_id, years),
231        }
232    }
233
234    /// Устанавливает массив `i_ids`.
235    #[must_use]
236    #[inline]
237    pub fn with_i_ids<I>(mut self, ids: I) -> Self
238    where
239        I: IntoIterator<Item = IndicatorId>,
240    {
241        self.inner = self.inner.with_i_ids(ids);
242        self
243    }
244
245    /// Устанавливает массив `m1_ids`.
246    #[must_use]
247    #[inline]
248    pub fn with_m1_ids<I>(mut self, ids: I) -> Self
249    where
250        I: IntoIterator<Item = MeasureId>,
251    {
252        self.inner = self.inner.with_m1_ids(ids);
253        self
254    }
255
256    /// Устанавливает массив `m2_ids`.
257    #[must_use]
258    #[inline]
259    pub fn with_m2_ids<I>(mut self, ids: I) -> Self
260    where
261        I: IntoIterator<Item = MeasureId>,
262    {
263        self.inner = self.inner.with_m2_ids(ids);
264        self
265    }
266
267    /// Возвращает идентификатор категории.
268    #[must_use]
269    #[inline]
270    pub fn category_id(&self) -> CategoryId {
271        self.inner.root_id()
272    }
273
274    /// Возвращает диапазон годов.
275    #[must_use]
276    #[inline]
277    pub fn years(&self) -> YearSpan {
278        self.inner.years()
279    }
280
281    /// Возвращает фильтр `i_ids`.
282    #[must_use]
283    #[inline]
284    pub fn i_ids(&self) -> &[IndicatorId] {
285        self.inner.i_ids()
286    }
287
288    /// Возвращает фильтр `m1_ids`.
289    #[must_use]
290    #[inline]
291    pub fn m1_ids(&self) -> &[MeasureId] {
292        self.inner.m1_ids()
293    }
294
295    /// Возвращает фильтр `m2_ids`.
296    #[must_use]
297    #[inline]
298    pub fn m2_ids(&self) -> &[MeasureId] {
299        self.inner.m2_ids()
300    }
301}
302
303impl Serialize for DataNewQuery {
304    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
305    where
306        S: Serializer,
307    {
308        serialize_multi_ids_query(serializer, "categoryId", &self.inner)
309    }
310}
311
312#[derive(Debug, Clone)]
313struct MultiIdsQuery<RootId> {
314    root_id: RootId,
315    years: YearsRangeQuery,
316    i_ids: Vec<IndicatorId>,
317    m1_ids: Vec<MeasureId>,
318    m2_ids: Vec<MeasureId>,
319}
320
321impl<RootId: Copy> MultiIdsQuery<RootId> {
322    #[inline]
323    fn new(root_id: RootId, years: YearSpan) -> Self {
324        Self {
325            root_id,
326            years: YearsRangeQuery::from_span(years),
327            i_ids: Vec::new(),
328            m1_ids: Vec::new(),
329            m2_ids: Vec::new(),
330        }
331    }
332
333    #[inline]
334    fn with_i_ids<I>(mut self, ids: I) -> Self
335    where
336        I: IntoIterator<Item = IndicatorId>,
337    {
338        self.i_ids = ids.into_iter().collect();
339        self
340    }
341
342    #[inline]
343    fn with_m1_ids<I>(mut self, ids: I) -> Self
344    where
345        I: IntoIterator<Item = MeasureId>,
346    {
347        self.m1_ids = ids.into_iter().collect();
348        self
349    }
350
351    #[inline]
352    fn with_m2_ids<I>(mut self, ids: I) -> Self
353    where
354        I: IntoIterator<Item = MeasureId>,
355    {
356        self.m2_ids = ids.into_iter().collect();
357        self
358    }
359
360    #[inline]
361    fn root_id(&self) -> RootId {
362        self.root_id
363    }
364
365    #[inline]
366    fn years(&self) -> YearSpan {
367        self.years.span()
368    }
369
370    #[inline]
371    fn i_ids(&self) -> &[IndicatorId] {
372        &self.i_ids
373    }
374
375    #[inline]
376    fn m1_ids(&self) -> &[MeasureId] {
377        &self.m1_ids
378    }
379
380    #[inline]
381    fn m2_ids(&self) -> &[MeasureId] {
382        &self.m2_ids
383    }
384}
385
386fn serialize_multi_ids_query<S, RootId>(
387    serializer: S,
388    root_key: &'static str,
389    query: &MultiIdsQuery<RootId>,
390) -> Result<S::Ok, S::Error>
391where
392    S: Serializer,
393    RootId: Copy + Serialize,
394{
395    let mut seq = serializer.serialize_seq(Some(
396        3 + query.i_ids.len() + query.m1_ids.len() + query.m2_ids.len(),
397    ))?;
398    seq.serialize_element(&(root_key, query.root_id))?;
399    seq.serialize_element(&("y1", query.years.start()))?;
400    seq.serialize_element(&("y2", query.years.end()))?;
401    serialize_repeated_ids(&mut seq, "i_ids", &query.i_ids)?;
402    serialize_repeated_ids(&mut seq, "m1_ids", &query.m1_ids)?;
403    serialize_repeated_ids(&mut seq, "m2_ids", &query.m2_ids)?;
404    seq.end()
405}
406
407fn serialize_repeated_ids<S, Id>(seq: &mut S, key: &'static str, ids: &[Id]) -> Result<(), S::Error>
408where
409    S: SerializeSeq,
410    Id: Copy + Serialize,
411{
412    for &id in ids {
413        seq.serialize_element(&(key, id))?;
414    }
415
416    Ok(())
417}
418
419#[derive(Debug, Clone, Copy, Serialize)]
420pub(crate) struct PublicationIdQuery {
421    #[serde(rename = "publicationId")]
422    publication_id: PublicationId,
423}
424
425#[inline]
426pub(crate) fn publication_id_query(publication_id: PublicationId) -> PublicationIdQuery {
427    PublicationIdQuery { publication_id }
428}
429
430#[derive(Debug, Clone, Copy, Serialize)]
431pub(crate) struct DatasetIdQuery {
432    #[serde(rename = "datasetId")]
433    dataset_id: DatasetId,
434}
435
436#[inline]
437pub(crate) fn dataset_id_query(dataset_id: DatasetId) -> DatasetIdQuery {
438    DatasetIdQuery { dataset_id }
439}
440
441#[derive(Debug, Clone, Copy, Serialize)]
442pub(crate) struct YearsQuery {
443    #[serde(rename = "datasetId")]
444    dataset_id: DatasetId,
445    #[serde(rename = "measureId", skip_serializing_if = "Option::is_none")]
446    measure_id: Option<MeasureId>,
447}
448
449#[inline]
450pub(crate) fn years_query(dataset_id: DatasetId, measure_id: Option<MeasureId>) -> YearsQuery {
451    YearsQuery {
452        dataset_id,
453        measure_id,
454    }
455}
456
457#[derive(Debug)]
458pub(crate) struct YearsExQuery<'a> {
459    publication_id: PublicationId,
460    ids: &'a [DatasetId],
461}
462
463#[inline]
464pub(crate) fn years_ex_query(publication_id: PublicationId, ids: &[DatasetId]) -> YearsExQuery<'_> {
465    YearsExQuery {
466        publication_id,
467        ids,
468    }
469}
470
471impl Serialize for YearsExQuery<'_> {
472    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
473    where
474        S: Serializer,
475    {
476        let mut seq = serializer.serialize_seq(Some(1 + self.ids.len()))?;
477        seq.serialize_element(&("publicationId", self.publication_id))?;
478        serialize_repeated_ids(&mut seq, "ids", self.ids)?;
479        seq.end()
480    }
481}