fred_rs/source/releases.rs
1//! Get the releases for a source
2//!
3//! [https://research.stlouisfed.org/docs/api/fred/source_releases.html](https://research.stlouisfed.org/docs/api/fred/source_releases.html
4//!
5//! ```
6//! use fred_rs::client::FredClient;
7//! use fred_rs::source::releases::{Builder, SortOrder, OrderBy};
8//! use fred_rs::release::Response;
9//!
10//! let mut c = match FredClient::new() {
11//! Ok(c) => c,
12//! Err(msg) => {
13//! println!("{}", msg);
14//! assert_eq!(2, 1);
15//! return
16//! },
17//! };
18//!
19//! let mut builder = Builder::new();
20//! builder
21//! .limit(5)
22//! .order_by(OrderBy::Name)
23//! .sort_order(SortOrder::Descending);
24//!
25//! let resp: Response = match c.source_releases(1, Some(builder)) {
26//! Ok(resp) => resp,
27//! Err(msg) => {
28//! println!("{}", msg);
29//! assert_eq!(2, 1);
30//! return
31//! },
32//! };
33//!
34//! for item in resp.releases {
35//! match item.link {
36//! Some(l) => println!("{}: {}", item.name, l),
37//! None => println!("{}: No Link", item.name),
38//! }
39//! }
40//! ```
41
42/// Determines the order of search results
43///
44/// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#order_by](https://research.stlouisfed.org/docs/api/fred/source_releases.html#order_by)
45pub enum OrderBy {
46 /// Default
47 ReleaseId,
48 Name,
49 PressRelease,
50 RealtimeStart,
51 RealtimeEnd,
52}
53
54/// Sort order options for the fred/source/releases endpoint
55///
56/// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#sort_order](https://research.stlouisfed.org/docs/api/fred/source_releases.html#sort_order)
57pub enum SortOrder {
58 /// Dates returned in ascending order (default)
59 Ascending,
60 /// Dates returned in descending order
61 Descending,
62}
63
64pub struct Builder {
65 option_string: String,
66}
67
68impl Builder {
69
70 /// Initializes a new sources::Builder that can be used to add commands to an API request
71 ///
72 /// The builder does not do validity checking of the arguments nor does it check for duplicates.
73 ///
74 /// ```
75 /// use fred_rs::sources::Builder;
76 /// // Create a new builder
77 /// let mut builder = Builder::new();
78 /// // add arguments to the builder
79 /// builder
80 /// .realtime_start("1900-01-01")
81 /// .realtime_end("2000-01-01");
82 /// ```
83 pub fn new() -> Builder {
84 Builder {
85 option_string: String::new(),
86 }
87 }
88
89 /// Returns the current arguments as a URL formatted string
90 pub(crate) fn build(self) -> String {
91 self.option_string
92 }
93
94 /// Adds a realtime_start argument to the builder
95 ///
96 /// # Arguments
97 /// * `start_date` - date formatted as YYYY-MM-DD
98 ///
99 /// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#realtime_start](https://research.stlouisfed.org/docs/api/fred/source_releases.html#realtime_start)
100 pub fn realtime_start(&mut self, start_date: &str) -> &mut Builder {
101 self.option_string += format!("&realtime_start={}", start_date).as_str();
102 self
103 }
104
105 /// Adds a realtime_end argument to the builder
106 ///
107 /// # Arguments
108 /// * `end_date` - date formatted as YYYY-MM-DD
109 ///
110 /// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#realtime_end](https://research.stlouisfed.org/docs/api/fred/source_releases.html#realtime_end)
111 pub fn realtime_end(&mut self, end_date: &str) -> &mut Builder {
112 self.option_string += format!("&realtime_end={}", end_date).as_str();
113 self
114 }
115
116 /// Adds a limit argument to the builder
117 ///
118 /// The limit argument specifies a maximum number of observations to return.
119 ///
120 /// # Arguments
121 /// * `num_results` - Maximum number of results to return
122 ///
123 /// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#limit](https://research.stlouisfed.org/docs/api/fred/source_releases.html#limit)
124 pub fn limit(&mut self, num_results: usize) -> &mut Builder {
125 let num_results = if num_results > 1000 { // max value is 1000
126 1000
127 } else {
128 num_results
129 };
130 self.option_string += format!("&limit={}", num_results).as_str();
131 self
132 }
133
134 /// Adds an offset argument to the builder
135 ///
136 /// 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.
137 ///
138 /// # Arguments
139 /// * `ofs` - the offset amount
140 ///
141 /// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#offset](https://research.stlouisfed.org/docs/api/fred/source_releases.html#offset)
142 pub fn offset(&mut self, ofs: usize) -> &mut Builder {
143 self.option_string += format!("&offset={}", ofs).as_str();
144 self
145 }
146
147 /// Adds the search_type argument to the request
148 ///
149 /// # Arguments
150 /// * `order` - result ranking system
151 ///
152 /// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#order_by](https://research.stlouisfed.org/docs/api/fred/source_releases.html#order_by)
153 pub fn order_by(&mut self, order: OrderBy) -> &mut Builder {
154 match order {
155 OrderBy::ReleaseId => {
156 self.option_string += "&order_by=release_id";
157 },
158 OrderBy::Name => {
159 self.option_string += "&order_by=name";
160 },
161 OrderBy::PressRelease => {
162 self.option_string += "&order_by=press_release";
163 },
164 OrderBy::RealtimeStart => {
165 self.option_string += "&order_by=realtime_start";
166 },
167 OrderBy::RealtimeEnd => {
168 self.option_string += "&order_by=realtime_end";
169 },
170 };
171 self
172 }
173
174 /// Change the sort order of the data
175 ///
176 /// # Arguments
177 /// * `order` - Data sort order enum
178 ///
179 /// [https://research.stlouisfed.org/docs/api/fred/source_releases.html#sort_order](https://research.stlouisfed.org/docs/api/fred/source_releases.html#sort_order)
180 pub fn sort_order(&mut self, order: SortOrder) -> &mut Builder {
181 match order {
182 SortOrder::Descending => {
183 self.option_string += format!("&sort_order=desc").as_str()
184 },
185 _ => () // ASC is the default so do nothing
186 }
187 self
188 }
189
190}
191
192#[cfg(test)]
193mod tests {
194 use super::*;
195 use crate::release::Response;
196 use crate::client::FredClient;
197
198 #[test]
199 fn source_releases_with_options() {
200 let mut c = match FredClient::new() {
201 Ok(c) => c,
202 Err(msg) => {
203 println!("{}", msg);
204 assert_eq!(2, 1);
205 return
206 },
207 };
208
209 let mut builder = Builder::new();
210 builder
211 .limit(5)
212 .order_by(OrderBy::Name)
213 .sort_order(SortOrder::Descending);
214
215 let resp: Response = match c.source_releases(1, Some(builder)) {
216 Ok(resp) => resp,
217 Err(msg) => {
218 println!("{}", msg);
219 assert_eq!(2, 1);
220 return
221 },
222 };
223
224 for item in resp.releases {
225 match item.link {
226 Some(l) => println!("{}: {}", item.name, l),
227 None => println!("{}: No Link", item.name),
228 }
229 }
230 }
231}