fred_rs/source/
mod.rs

1//! Get a source of economic data
2//! 
3//! [https://research.stlouisfed.org/docs/api/fred/source.html](https://research.stlouisfed.org/docs/api/fred/source.html)
4//! 
5//! ```
6//! use fred_rs::client::FredClient;
7//! use fred_rs::source::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 resp: Response = match c.source(1, None) {
19//!     Ok(resp) => resp,
20//!     Err(msg) => {
21//!         println!("{}", msg);
22//!         assert_eq!(2, 1);
23//!         return
24//!     },
25//! };
26//! 
27//! for item in resp.sources {
28//!     match item.link {
29//!         Some(l) => println!("{}: {}", item.name, l),
30//!         None => println!("{}: null", item.name),
31//!     }
32//! }
33//! ```
34
35pub mod releases;
36
37// -----------------------------------------------------------------------------
38
39use serde::Deserialize;
40use std::fmt::{self, Display, Formatter};
41
42#[derive(Deserialize, Clone, Debug, Default)]
43/// Response data structure for the fred/source endpoint
44/// 
45/// [https://research.stlouisfed.org/docs/api/fred/source.html] (https://research.stlouisfed.org/docs/api/fred/source.html)
46pub struct Response {
47    /// The Real Time start date for the request
48    pub realtime_start: String,
49    /// The Real Time end data for the request
50    pub realtime_end: String,
51    /// How the results are ordered
52    pub order_by: Option<String>,
53    // Results are listed in ascending or descending
54    pub sort_order: Option<String>,
55    /// Number of results returned
56    pub count: Option<usize>,
57    /// ???
58    pub offset: Option<usize>,
59    /// Maximum number of results to return
60    pub limit: Option<usize>,
61    /// Series returned by the search
62    pub sources: Vec<Source>,
63}
64
65impl Display for Response {
66    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
67        for item in self.sources.iter() {
68            match item.fmt(f) {
69                Ok(_) => (),
70                Err(e) => return Err(e),
71            }
72            match writeln!(f, "") {
73                Ok(_) => (),
74                Err(e) => return Err(e),
75            }
76        }
77        Ok(())
78    }
79}
80
81#[derive(Deserialize, Clone, Debug, Default)]
82/// Data structure containing infomation about a particular tag
83/// 
84/// [https://research.stlouisfed.org/docs/api/fred/source.html](https://research.stlouisfed.org/docs/api/fred/source.html)
85pub struct Source {
86    /// The source ID
87    pub id: usize,
88    /// The Real Time start date for the request
89    pub realtime_start: String,
90    /// The Real Time end data for the request
91    pub realtime_end: String,
92    /// The source name
93    pub name: String,
94    /// A link to the source's website
95    pub link: Option<String>,
96    /// Additional notes about the source
97    pub notes: Option<String>
98}
99
100impl Display for Source {
101    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
102        write!(f, "Soruce {}: {}", self.id, self.name)
103    }
104}
105
106pub struct Builder {
107    option_string: String,
108}
109
110impl Builder {
111
112    /// Initializes a new sources::Builder that can be used to add commands to an API request
113    /// 
114    /// The builder does not do validity checking of the arguments nor does it check for duplicates.
115    /// 
116    /// ```
117    /// use fred_rs::sources::Builder;
118    /// // Create a new builder
119    /// let mut builder = Builder::new();
120    /// // add arguments to the builder
121    /// builder
122    ///     .realtime_start("1900-01-01")
123    ///     .realtime_end("2000-01-01");
124    /// ```
125    pub fn new() -> Builder {
126        Builder {
127            option_string: String::new(),
128        }
129    }
130
131    /// Returns the current arguments as a URL formatted string
132    pub(crate) fn build(self) -> String {
133        self.option_string
134    }
135
136    /// Adds a realtime_start argument to the builder
137    /// 
138    /// # Arguments
139    /// * `start_date` - date formatted as YYYY-MM-DD
140    /// 
141    /// [https://research.stlouisfed.org/docs/api/fred/source.html#realtime_start](https://research.stlouisfed.org/docs/api/fred/source.html#realtime_start)
142    pub fn realtime_start(&mut self, start_date: &str) -> &mut Builder {
143        self.option_string += format!("&realtime_start={}", start_date).as_str();
144        self
145    }
146
147    /// Adds a realtime_end argument to the builder
148    /// 
149    /// # Arguments
150    /// * `end_date` - date formatted as YYYY-MM-DD
151    /// 
152    /// [https://research.stlouisfed.org/docs/api/fred/source.html#realtime_end](https://research.stlouisfed.org/docs/api/fred/source.html#realtime_end)
153    pub fn realtime_end(&mut self, end_date: &str) -> &mut Builder {
154        self.option_string += format!("&realtime_end={}", end_date).as_str();
155        self
156    }
157
158}
159
160#[cfg(test)]
161mod tests {
162    use super::*;
163    use crate::client::FredClient;
164
165    #[test]
166    fn source_no_options() {
167        let mut c = match FredClient::new() {
168            Ok(c) => c,
169            Err(msg) => {
170                println!("{}", msg);
171                assert_eq!(2, 1);
172                return
173            },
174        };
175
176        let resp: Response = match c.source(1, None) {
177            Ok(resp) => resp,
178            Err(msg) => {
179                println!("{}", msg);
180                assert_eq!(2, 1);
181                return
182            },
183        };
184
185        for s in resp.sources {
186            match s.link {
187                Some(l) => println!("{}: {}", s.name, l),
188                None => println!("{}", s.name)
189            }
190        }
191    } 
192}