fred_rs/series/
mod.rs

1//! Get an economic data series
2//! 
3//! [https://research.stlouisfed.org/docs/api/fred/series.html](https://research.stlouisfed.org/docs/api/fred/series.html)
4//! 
5//! ```
6//! use fred_rs::client::FredClient;
7//! use fred_rs::series::{Builder, Response};
8//! 
9//! let mut c = match FredClient::new() {
10//!     Ok(c) => c,
11//!     Err(msg) => {
12//!         println!("{}", msg);
13//!         assert_eq!(2, 1);
14//!         return
15//!     },
16//! };
17//! 
18//! let mut builder = Builder::new();
19//! builder.realtime_start("2000-01-01");
20//! 
21//! let resp: Response = match c.series("UNRATE", Some(builder)) {
22//!     Ok(resp) => resp,
23//!     Err(msg) => {
24//!         println!("{}", msg);
25//!         assert_eq!(2, 1);
26//!         return
27//!     },
28//! };
29//! 
30//! for item in resp.seriess {
31//!     println!(
32//!         "{}: {} {} {}",
33//!         item.id,
34//!         item.title,
35//!         item.realtime_start,
36//!         item.realtime_end
37//!     );
38//! }
39//! ```
40
41pub mod categories;
42pub mod observation;
43pub mod release;
44pub mod tags;
45pub mod search;
46pub mod updates;
47pub mod vintagedates;
48
49// ----------------------------------------------------------------------------
50use serde::Deserialize;
51use std::fmt::{self, Display, Formatter};
52
53#[derive(Deserialize, Clone, Debug, Default)]
54/// Response data structure for the fred/series endpoint
55/// 
56/// Order_by, sort_order, count, offset and limit are used by endpoints which return a list of series.  They can be ignored for the fred/series endpoint.
57/// 
58/// [https://research.stlouisfed.org/docs/api/fred/series.html] (https://research.stlouisfed.org/docs/api/fred/series.html)
59pub struct Response {
60    /// The Real Time start date for the request
61    pub realtime_start: String,
62    /// The Real Time end data for the request
63    pub realtime_end: String,
64    /// How the results are ordered
65    pub order_by: Option<String>,
66    /// Results can be ascending (asc) or descending (desc)
67    pub sort_order: Option<String>,
68    /// Number of results returned
69    pub count: Option<usize>,
70    /// ???
71    pub offset: Option<usize>,
72    /// Maximum number of results to return
73    pub limit: Option<usize>,
74    /// Series matching the requested series_id
75    /// 
76    /// The fred/series endpoint will return a series for each time a series changed.  For example Real GNP has been calculated several different ways over time so this endpoint will return a different series for each time period becasue they all fit under the same symbol: GNPCA.
77    pub seriess: Vec<Series>,
78}
79
80impl Display for Response {
81    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
82        for item in self.seriess.iter() {
83            match item.fmt(f) {
84                Ok(_) => (),
85                Err(e) => return Err(e),
86            }
87            match writeln!(f, "") {
88                Ok(_) => (),
89                Err(e) => return Err(e),
90            }
91        }
92        Ok(())
93    }
94}
95
96#[derive(Deserialize, Clone, Debug, Default)]
97/// Data structure containing infomation about a particular data series
98/// 
99/// [https://research.stlouisfed.org/docs/api/fred/series.html](https://research.stlouisfed.org/docs/api/fred/series.html)
100pub struct Series {
101    /// The series ID name
102    pub id: String,
103    /// The Real Time start of the series
104    pub realtime_start: String,
105    /// The Real Time end of the series
106    pub realtime_end: String,
107    /// The series title
108    pub title: String,
109    /// The series start date
110    pub observation_start: String,
111    /// The series end date
112    pub observation_end: String,
113    /// The series natural frequency (See [series::observation::Frequency])
114    pub frequency: String,
115    /// Short form of the frequency
116    pub frequency_short: String,
117    /// The data series units (e.g. Billions of Chanined 2009 Dollars)
118    pub units: String,
119    // Short form of the units (e.g. Bil. of Chn. 2009 $)
120    pub units_short: String,
121    /// Seasonal Adjustment Information
122    pub seasonal_adjustment: String,
123    /// Short form of the Seasonal Adjustment Info
124    pub seasonal_adjustment_short: String,
125    /// Date on whih the series was last updated
126    pub last_updated: String,
127    /// Popularity score
128    pub popularity: isize,
129    /// Group popularity score
130    pub group_popularity: Option<isize>,
131    /// Additional Notes
132    pub notes: Option<String>,
133}
134
135impl Display for Series {
136    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
137        write!(f, "Series {}: {}", self.id, self.title)
138    }
139}
140
141pub struct Builder {
142    option_string: String
143}
144
145impl Builder {
146
147    /// Initializes a new series::Builder that can be used to add commands to an API request
148    /// 
149    /// The builder does not do validity checking of the arguments nor does it check for duplicates.
150    /// 
151    /// ```
152    /// use fred_rs::series::Builder;
153    /// // Create a new builder
154    /// let mut builder = Builder::new();
155    /// // add arguments to the builder
156    /// builder
157    ///     .realtime_start("1900-01-01")
158    ///     .realtime_end("2000-01-01");
159    /// ```
160    pub fn new() -> Builder {
161        Builder {
162            option_string: String::new(),
163        }
164    }
165
166    /// Returns the current arguments as a URL formatted string
167    pub(crate) fn build(self) -> String {
168        self.option_string
169    }
170
171    /// Adds a realtime_start argument to the builder
172    /// 
173    /// # Arguments
174    /// * `start_date` - date formatted as YYYY-MM-DD
175    /// 
176    /// [https://research.stlouisfed.org/docs/api/fred/series.html#realtime_start](https://research.stlouisfed.org/docs/api/fred/series.html#realtime_start)
177    pub fn realtime_start(&mut self, start_date: &str) -> &mut Builder {
178        self.option_string += format!("&realtime_start={}", start_date).as_str();
179        self
180    }
181
182    /// Adds a realtime_end argument to the builder
183    /// 
184    /// # Arguments
185    /// * `end_date` - date formatted as YYYY-MM-DD
186    /// 
187    /// [https://research.stlouisfed.org/docs/api/fred/series.html#realtime_end](https://research.stlouisfed.org/docs/api/fred/series.html#realtime_end)
188    pub fn realtime_end(&mut self, end_date: &str) -> &mut Builder {
189        self.option_string += format!("&realtime_end={}", end_date).as_str();
190        self
191    }
192}
193
194#[cfg(test)]
195mod tests {
196    use super::*;
197    use crate::client::FredClient;
198
199    #[test]
200    fn series_with_options() {
201        let mut c = match FredClient::new() {
202            Ok(c) => c,
203            Err(msg) => {
204                println!("{}", msg);
205                assert_eq!(2, 1);
206                return
207            },
208        };
209
210        let mut builder = Builder::new();
211        builder
212            .realtime_start("2000-01-01");
213
214        let resp: Response = match c.series("UNRATE", Some(builder)) {
215            Ok(resp) => resp,
216            Err(msg) => {
217                println!("{}", msg);
218                assert_eq!(2, 1);
219                return
220            },
221        };
222
223        for item in resp.seriess {
224            println!("{}: {} {} {}", item.id, item.title, item.realtime_start, item.realtime_end);
225        }
226    } 
227}