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}