1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::{Client, ReleaseDatesResults, Result, SortOrder};
/// A builder for the release-date endpoints, returned by
/// [`Client::releases_dates`] (`fred/releases/dates`, the publication dates of
/// *every* release) and [`Client::release_dates`] (`fred/release/dates`, the
/// dates of *one* release). Both share optional sort, paging, and the
/// "include dates with no data" toggle and return [`ReleaseDatesResults`];
/// `release_dates` additionally carries the `release_id`. Finish with
/// [`send`](ReleaseDatesRequest::send).
///
/// ```no_run
/// # async fn run(client: &ferric_fred::Client) -> ferric_fred::Result<()> {
/// let calendar = client.releases_dates().limit(20).send().await?;
/// println!("{} release dates", calendar.count);
/// # Ok(())
/// # }
/// ```
#[derive(Debug, Clone)]
#[must_use = "a ReleaseDatesRequest does nothing until you call `.send()`"]
pub struct ReleaseDatesRequest<'a> {
client: &'a Client,
/// The endpoint path, `/releases/dates` or `/release/dates`.
path: &'static str,
/// FRED's `release_id`; required by `/release/dates`, absent for
/// `/releases/dates`.
release_id: Option<String>,
sort_order: Option<SortOrder>,
limit: Option<u32>,
offset: Option<u32>,
include_dates_with_no_data: Option<bool>,
}
impl<'a> ReleaseDatesRequest<'a> {
pub(crate) fn new(client: &'a Client, path: &'static str) -> Self {
Self {
client,
path,
release_id: None,
sort_order: None,
limit: None,
offset: None,
include_dates_with_no_data: None,
}
}
/// Construct a request for `/release/dates` scoped to one release.
pub(crate) fn with_release(client: &'a Client, path: &'static str, release_id: String) -> Self {
Self {
release_id: Some(release_id),
..Self::new(client, path)
}
}
/// The endpoint path this request targets (used by the client to dispatch).
pub(crate) fn path(&self) -> &'static str {
self.path
}
/// Sort order of the dates (`sort_order`).
pub fn sort_order(mut self, order: SortOrder) -> Self {
self.sort_order = Some(order);
self
}
/// Maximum number of results to return, `1..=10000` (`limit`).
pub fn limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
/// Number of results to skip from the start (`offset`), for paging.
pub fn offset(mut self, offset: u32) -> Self {
self.offset = Some(offset);
self
}
/// Include release dates for which no observations have yet been released
/// (`include_release_dates_with_no_data`) — e.g. a scheduled future date.
/// FRED omits these by default.
pub fn include_dates_with_no_data(mut self, include: bool) -> Self {
self.include_dates_with_no_data = Some(include);
self
}
/// Run the request and return a page of release dates with pagination
/// metadata.
///
/// # Errors
///
/// Returns an error if the request fails to send, FRED returns a non-success
/// status, or the response body cannot be deserialized.
pub async fn send(self) -> Result<ReleaseDatesResults> {
self.client.execute_release_dates(&self).await
}
/// Serialize the set parameters to FRED query key/value pairs. `api_key` and
/// `file_type` are added by the client, not here.
pub(crate) fn query_params(&self) -> Vec<(&'static str, String)> {
let mut params: Vec<(&'static str, String)> = Vec::new();
if let Some(release_id) = &self.release_id {
params.push(("release_id", release_id.clone()));
}
if let Some(order) = self.sort_order {
params.push(("sort_order", order.query_code().to_owned()));
}
if let Some(limit) = self.limit {
params.push(("limit", limit.to_string()));
}
if let Some(offset) = self.offset {
params.push(("offset", offset.to_string()));
}
if let Some(include) = self.include_dates_with_no_data {
params.push(("include_release_dates_with_no_data", include.to_string()));
}
params
}
}