fxapi_rs/api/
mod.rs

1//! Module that contains the main [Fxapi] struct
2
3use std::sync::Arc;
4use reqwest::Client;
5use crate::error::FxapiError;
6use crate::{error, models, utils};
7use crate::utils::baseline::construct_base_url;
8
9/// Settings struct that contains the api key
10#[derive(Debug, Clone)]
11pub struct Settings {
12    api_key: String,
13}
14
15/// The main struct of the crate giving access to the fxapi.
16/// Create a new instance of the struct with your api key as parameter.
17#[derive(Debug, Clone)]
18pub struct Fxapi {
19    client: Client,
20    settings: Arc<Settings>,
21}
22
23impl<'a> Fxapi {
24    /// Creates a new instance of the Fxapi struct by passing your api key as
25    /// function parameter.
26    pub fn new(api_key: &'a str) -> Result<Self, FxapiError> {
27        let settings = std::sync::Arc::new(Settings {
28            api_key: String::from(api_key),
29        });
30        let client = utils::baseline::construct_client(None, &settings)?;
31        Ok(Self { client, settings })
32    }
33
34    pub async fn status(
35        &self,
36    ) -> Result<models::DetailsResponse, error::FxapiError> {
37        let mut url = construct_base_url(&self.settings.api_key, Some("status"))?;
38        let res_body = self
39            .client
40            .get(url)
41            .send()
42            .await
43            .map_err(|err| error::FxapiError::RequestError { source: err })?
44            .text()
45            .await
46            .map_err(|err| error::FxapiError::RequestError { source: err })?;
47        serde_json::from_str::<models::DetailsResponse>(&res_body)
48            .map_err(|_| error::FxapiError::ResponseParsingError { body: res_body })
49    }
50
51    pub async fn currencies(
52        &self,
53    ) -> Result<models::DetailsResponse, error::FxapiError> {
54        let mut url = construct_base_url(&self.settings.api_key, Some("currencies"))?;
55        let res_body = self
56            .client
57            .get(url)
58            .send()
59            .await
60            .map_err(|err| error::FxapiError::RequestError { source: err })?
61            .text()
62            .await
63            .map_err(|err| error::FxapiError::RequestError { source: err })?;
64        serde_json::from_str::<models::DetailsResponse>(&res_body)
65            .map_err(|_| error::FxapiError::ResponseParsingError { body: res_body })
66    }
67
68    pub async fn latest(
69        &self,
70        base_currency: &'a str,
71        currencies: &'a str,
72    ) -> Result<models::DetailsResponse, error::FxapiError> {
73        let mut url = construct_base_url(&self.settings.api_key, Some("latest"))?;
74        url.query_pairs_mut()
75            .append_pair("base_currency", base_currency)
76            .append_pair("currencies", currencies);
77        let res_body = self
78            .client
79            .get(url)
80            .send()
81            .await
82            .map_err(|err| error::FxapiError::RequestError { source: err })?
83            .text()
84            .await
85            .map_err(|err| error::FxapiError::RequestError { source: err })?;
86        serde_json::from_str::<models::DetailsResponse>(&res_body)
87            .map_err(|_| error::FxapiError::ResponseParsingError { body: res_body })
88    }
89
90    pub async fn historical(
91        &self,
92        base_currency: &'a str,
93        date: &'a str,
94        currencies: &'a str,
95    ) -> Result<models::DetailsResponse, error::FxapiError> {
96        let mut url = construct_base_url(&self.settings.api_key, Some("historical"))?;
97        url.query_pairs_mut()
98            .append_pair("base_currency", base_currency)
99            .append_pair("date", date)
100            .append_pair("currencies", currencies);
101        let res_body = self
102            .client
103            .get(url)
104            .send()
105            .await
106            .map_err(|err| error::FxapiError::RequestError { source: err })?
107            .text()
108            .await
109            .map_err(|err| error::FxapiError::RequestError { source: err })?;
110        serde_json::from_str::<models::DetailsResponse>(&res_body)
111            .map_err(|_| error::FxapiError::ResponseParsingError { body: res_body })
112    }
113
114    pub async fn convert(
115        &self,
116        base_currency: &'a str,
117        date: &'a str,
118        value: i8,
119        currencies: &'a str,
120    ) -> Result<models::DetailsResponse, error::FxapiError> {
121        let mut url = construct_base_url(&self.settings.api_key, Some("convert"))?;
122        url.query_pairs_mut()
123            .append_pair("base_currency", base_currency)
124            .append_pair("date", date)
125            .append_pair("value", &value.to_string())
126            .append_pair("currencies", currencies);
127        let res_body = self
128            .client
129            .get(url)
130            .send()
131            .await
132            .map_err(|err| error::FxapiError::RequestError { source: err })?
133            .text()
134            .await
135            .map_err(|err| error::FxapiError::RequestError { source: err })?;
136        serde_json::from_str::<models::DetailsResponse>(&res_body)
137            .map_err(|_| error::FxapiError::ResponseParsingError { body: res_body })
138    }
139
140    pub async fn range(
141        &self,
142        base_currency: &'a str,
143        datetime_start: &'a str,
144        datetime_end: &'a str,
145        currencies: &'a str,
146        accuracy: &'a str,
147    ) -> Result<models::DetailsResponse, error::FxapiError> {
148        let mut url = construct_base_url(&self.settings.api_key, Some("range"))?;
149        url.query_pairs_mut()
150            .append_pair("base_currency", base_currency)
151            .append_pair("datetime_start", datetime_start)
152            .append_pair("datetime_end", datetime_end)
153            .append_pair("accuracy", accuracy)
154            .append_pair("currencies", currencies);
155        let res_body = self
156            .client
157            .get(url)
158            .send()
159            .await
160            .map_err(|err| error::FxapiError::RequestError { source: err })?
161            .text()
162            .await
163            .map_err(|err| error::FxapiError::RequestError { source: err })?;
164        serde_json::from_str::<models::DetailsResponse>(&res_body)
165            .map_err(|_| error::FxapiError::ResponseParsingError { body: res_body })
166    }
167}