fred_rs/releases/
dates.rs

1//! Get release dates for all releases of economic data
2//! 
3//! [https://research.stlouisfed.org/docs/api/fred/releases_dates.html](https://research.stlouisfed.org/docs/api/fred/releases_dates.html)
4//! 
5//! ```
6//! use fred_rs::client::FredClient;
7//! use fred_rs::releases::dates::{Builder, Response, OrderBy, SortOrder};
8//! 
9//! // Create the client object
10//! let mut c = match FredClient::new() {
11//!     Ok(c) => c,
12//!     Err(msg) => {
13//!         println!("{}", msg);
14//!         return
15//!     },
16//! };
17//! 
18//! // Create the argument builder
19//! let mut builder = Builder::new();
20//! builder
21//!     .limit(5)
22//!     .sort_order(SortOrder::Ascending)
23//!     .order_by(OrderBy::ReleaseId);
24//! 
25//! // Make the request and pass in the builder to apply the arguments
26//! let resp: Response = match c.releases_dates(Some(builder)) {
27//!     Ok(resp) => resp,
28//!     Err(msg) => {
29//!         println!("{}", msg);
30//!         return
31//!     },
32//! };
33//! ```
34
35use serde::Deserialize;
36use std::fmt::{self, Display, Formatter};
37
38#[derive(Deserialize, Clone, Debug, Default)]
39/// Response data structure for the fred/releases/dates endpoint
40/// 
41/// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html] (https://research.stlouisfed.org/docs/api/fred/releases_dates.html)
42pub struct Response {
43    /// The Real Time start date for the request
44    pub realtime_start: String,
45    /// The Real Time end data for the request
46    pub realtime_end: String,
47    /// How the results are ordered
48    pub order_by: String,
49    // Results are listed in ascending or descending order
50    pub sort_order: String,
51    /// Number of results returned
52    pub count: usize,
53    /// First result returned
54    pub offset: usize,
55    /// Maximum number of results to return
56    pub limit: usize,
57    /// List of release dates for a release
58    pub release_dates: Vec<ReleaseDate>,
59}
60
61impl Display for Response {
62    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
63        for item in self.release_dates.iter() {
64            match item.fmt(f) {
65                Ok(_) => (),
66                Err(e) => return Err(e),
67            }
68            match writeln!(f, "") {
69                Ok(_) => (),
70                Err(e) => return Err(e),
71            }
72        }
73        Ok(())
74    }
75}
76
77#[derive(Deserialize, Clone, Debug, Default)]
78/// Data structure containing infomation about a particular release
79/// 
80/// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html](https://research.stlouisfed.org/docs/api/fred/releases_dates.html)
81pub struct ReleaseDate {
82    /// The release ID number
83    pub release_id: usize,
84    /// The name of the release
85    pub release_name: Option<String>,
86    /// The date of the release
87    pub date: String,
88}
89
90impl Display for ReleaseDate {
91    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
92        write!(f, "Release Date {}: {}", self.release_id, self.date)
93    }
94}
95
96/// Determines the order of search results
97/// 
98/// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#order_by](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#order_by)
99pub enum OrderBy {
100    /// Default
101    ReleaseDate,
102    ReleaseId,
103    ReleaseName,
104}
105
106/// Sort order options for the fred/releases/dates endpoint
107/// 
108/// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#sort_order](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#sort_order)
109pub enum SortOrder {
110    /// Dates returned in ascending order
111    Ascending,    
112    /// Dates returned in descending order (default)
113    Descending,   
114}
115
116pub struct Builder {
117    option_string: String
118}
119
120impl Builder {
121
122    /// Initializes a new releases::Builder that can be used to add commands to an API request
123    /// 
124    /// The builder does not do validity checking of the arguments nor does it check for duplicates.
125    /// 
126    /// ```
127    /// use fred_rs::releases::dates::Builder;
128    /// // Create a new builder
129    /// let mut builder = Builder::new();
130    /// // add arguments to the builder
131    /// builder
132    ///     .realtime_start("1900-01-01")
133    ///     .realtime_end("2000-01-01");
134    /// ```
135    pub fn new() -> Builder {
136        Builder {
137            option_string: String::new(),
138        }
139    }
140
141    /// Returns the current arguments as a URL formatted string
142    pub(crate) fn build(self) -> String {
143        self.option_string
144    }
145
146    /// Adds a realtime_start argument to the builder
147    /// 
148    /// # Arguments
149    /// * `start_date` - date formatted as YYYY-MM-DD
150    /// 
151    /// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#realtime_start](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#realtime_start)
152    pub fn realtime_start(&mut self, start_date: &str) -> &mut Builder {
153        self.option_string += format!("&realtime_start={}", start_date).as_str();
154        self
155    }
156
157    /// Adds a realtime_end argument to the builder
158    /// 
159    /// # Arguments
160    /// * `end_date` - date formatted as YYYY-MM-DD
161    /// 
162    /// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#realtime_end](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#realtime_end)
163    pub fn realtime_end(&mut self, end_date: &str) -> &mut Builder {
164        self.option_string += format!("&realtime_end={}", end_date).as_str();
165        self
166    }
167
168    /// Adds a limit argument to the builder
169    /// 
170    /// The limit argument specifies a maximum number of observations to return.
171    /// 
172    /// # Arguments
173    /// * `num_results` - Maximum number of results to return
174    /// 
175    /// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#limit](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#limit)
176    pub fn limit(&mut self, num_results: usize) -> &mut Builder {
177        let num_results = if num_results > 1000 { // max value is 1000
178            1000
179        } else {
180            num_results
181        };
182        self.option_string += format!("&limit={}", num_results).as_str();
183        self
184    }
185
186    /// Adds an offset argument to the builder
187    /// 
188    /// Adding an offset shifts the starting result number.  For example, if limit is 5 and offset is 0 then results 1-5 will be returned, but if offset was 5 then results 6-10 would be returned.
189    /// 
190    /// # Arguments
191    /// * `ofs` - the offset amount
192    /// 
193    /// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#offset](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#offset)
194    pub fn offset(&mut self, ofs: usize) -> &mut Builder {
195        self.option_string += format!("&offset={}", ofs).as_str();
196        self
197    }
198
199    /// Adds the search_type argument to the request
200    /// 
201    /// # Arguments
202    /// * `order` - result ranking system
203    /// 
204    /// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#order_by](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#order_by)
205    pub fn order_by(&mut self, order: OrderBy) -> &mut Builder {
206        match order {
207            OrderBy::ReleaseDate => {
208                self.option_string += "&order_by=release_name";
209            },
210            OrderBy::ReleaseId => {
211                self.option_string += "&order_by=release_id";
212            },
213            OrderBy::ReleaseName => {
214                self.option_string += "&order_by=name";
215            },
216        };
217        self
218    }
219
220    /// Change the sort order of the data
221    /// 
222    /// # Arguments
223    /// * `order` - Data sort order enum
224    /// 
225    /// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#sort_order](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#sort_order)
226    pub fn sort_order(&mut self, order: SortOrder) -> &mut Builder {
227        match order {
228            SortOrder::Ascending => {
229                self.option_string += format!("&sort_order=asc").as_str()
230            },
231            _ => () // DESC is the default so do nothing
232        }
233        self
234    }
235
236    /// Include release dates with no data available
237    /// 
238    /// The default is false.  Calling this will set the argument to true.
239    /// 
240    /// [https://research.stlouisfed.org/docs/api/fred/releases_dates.html#include_release_dates_with_no_data](https://research.stlouisfed.org/docs/api/fred/releases_dates.html#include_release_dates_with_no_data)
241    pub fn include_release_dates_with_no_data(&mut self) -> &mut Builder {
242        self.option_string += format!(
243            "&include_release_dates_with_no_data=true"
244        ).as_str();
245        self
246    }
247}
248
249#[cfg(test)]
250mod tests {
251    use super::*;
252    use crate::client::FredClient;
253
254    #[test]
255    fn releases_dates_with_options() {
256        let mut c = match FredClient::new() {
257            Ok(c) => c,
258            Err(msg) => {
259                println!("{}", msg);
260                assert_eq!(2, 1);
261                return
262            },
263        };
264
265        let mut builder = Builder::new();
266        builder
267            .limit(5)
268            .sort_order(SortOrder::Ascending)
269            .order_by(OrderBy::ReleaseId);
270
271        let resp: Response = match c.releases_dates(Some(builder)) {
272            Ok(resp) => resp,
273            Err(msg) => {
274                println!("{}", msg);
275                assert_eq!(2, 1);
276                return
277            },
278        };
279
280        for item in resp.release_dates {
281            println!("{}: {} -> {}", item.date, item.release_id, item.release_name.unwrap());
282        }
283    } 
284}