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}