coinpaprika_api/tickers/
mod.rs

1use crate::client::{Client, Response};
2use crate::error::Error;
3use chrono::prelude::*;
4use reqwest_middleware::RequestBuilder;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8#[derive(Debug, Serialize, Deserialize)]
9/// Price data of a single cryptocurrency on coinpaprika.com
10pub struct Ticker {
11    pub id: String,
12    pub name: String,
13    pub symbol: String,
14    pub rank: isize,
15    pub circulating_supply: i64,
16    pub total_supply: i64,
17    pub max_supply: i64,
18    pub beta_value: f64,
19    pub first_data_at: String,
20    pub last_updated: String,
21    pub quotes: Value,
22}
23
24#[derive(Debug, Serialize, Deserialize)]
25/// Historical data for a given cryptocurrency on coinpaprika.com
26pub struct HistoricalTick {
27    /// RFC3999 (ISO-8601) format
28    pub timestamp: String,
29    pub price: f64,
30    pub volume_24h: i64,
31    pub market_cap: i64,
32}
33
34/// Request for getting data of all active cryptocurrencies on coinpaprika.com
35/// [/tickers](https://api.coinpaprika.com/#tag/Tickers/operation/getTickers)
36pub struct GetTickersRequest<'a> {
37    client: &'a Client,
38    quotes: Vec<String>,
39}
40
41impl<'a> GetTickersRequest<'a> {
42    pub fn new(client: &'a Client) -> Self {
43        Self {
44            client,
45            quotes: vec![],
46        }
47    }
48
49    /// List of quotes to return. Up to 3 quotes at once. Currently allowed values:
50    /// BTC, ETH, USD, EUR, PLN, KRW, GBP, CAD, JPY, RUB, TRY, NZD, AUD, CHF, UAH, HKD, SGD, NGN,
51    /// PHP, MXN, BRL, THB, CLP, CNY, CZK, DKK, HUF, IDR, ILS, INR, MYR, NOK, PKR, SEK, TWD, ZAR,
52    /// VND, BOB, COP, PEN, ARS, ISK
53    pub fn quotes(&mut self, quotes: Vec<&str>) -> &'a mut GetTickersRequest {
54        self.quotes = quotes.iter().map(|&q| String::from(q)).collect();
55        self
56    }
57
58    pub async fn send(&self) -> Result<Vec<Ticker>, Error> {
59        let query = match self.quotes.len() {
60            0 => vec![],
61            _ => vec![("quotes", self.quotes.join(","))],
62        };
63
64        let request: RequestBuilder = self
65            .client
66            .client
67            .get(format!("{}/tickers", self.client.api_url))
68            .query(&query);
69
70        let response: Response = self.client.request(request).await?;
71
72        let data: Vec<Ticker> = response.response.json().await?;
73
74        Ok(data)
75    }
76}
77
78/// Request for getting data of single cryptocurrency on coinpaprika.com
79/// [/ticker/{coin_id}](https://api.coinpaprika.com/#tag/Tickers/operation/getTickersById)
80pub struct GetTickerRequest<'a> {
81    client: &'a Client,
82    coin_id: String,
83    quotes: Vec<String>,
84}
85
86impl<'a> GetTickerRequest<'a> {
87    pub fn new(client: &'a Client, coin_id: &str) -> Self {
88        Self {
89            client,
90            coin_id: String::from(coin_id),
91            quotes: vec![],
92        }
93    }
94
95    /// List of quotes to return. Up to 3 quotes at once. Currently allowed values:
96    /// BTC, ETH, USD, EUR, PLN, KRW, GBP, CAD, JPY, RUB, TRY, NZD, AUD, CHF, UAH, HKD, SGD, NGN,
97    /// PHP, MXN, BRL, THB, CLP, CNY, CZK, DKK, HUF, IDR, ILS, INR, MYR, NOK, PKR, SEK, TWD, ZAR,
98    /// VND, BOB, COP, PEN, ARS, ISK
99    pub fn quotes(&mut self, quotes: Vec<&str>) -> &'a mut GetTickerRequest {
100        self.quotes = quotes.iter().map(|&q| String::from(q)).collect();
101        self
102    }
103
104    pub async fn send(&self) -> Result<Ticker, Error> {
105        let query = match self.quotes.len() {
106            0 => vec![],
107            _ => vec![("quotes", self.quotes.join(","))],
108        };
109
110        let request: RequestBuilder = self
111            .client
112            .client
113            .get(format!("{}/tickers/{}", self.client.api_url, self.coin_id))
114            .query(&query);
115
116        let response: Response = self.client.request(request).await?;
117
118        let data: Ticker = response.response.json().await?;
119
120        Ok(data)
121    }
122}
123
124/// Request for getting historical data for a given cryptocurrency on coinpaprika.com
125/// [/ticker/{coin_id}/historical](https://api.coinpaprika.com/#tag/Tickers/operation/getTickersHistoricalById)
126pub struct GetHistoricalTicksRequest<'a> {
127    client: &'a Client,
128    coin_id: String,
129    start: String,
130    end: Option<String>,
131    limit: Option<String>,
132    quote: Option<String>,
133    interval: Option<String>,
134}
135
136impl<'a> GetHistoricalTicksRequest<'a> {
137    pub fn new(client: &'a Client, coin_id: &str) -> Self {
138        let now: DateTime<Utc> = Utc::now(); // e.g. `2014-11-28T12:45:59.324310806Z`
139
140        Self {
141            client,
142            coin_id: String::from(coin_id),
143            start: format!("{}-{}-{}", now.year(), now.month(), now.day()),
144            end: None,
145            limit: None,
146            quote: None,
147            interval: None,
148        }
149    }
150
151    /// Start point for historical data
152    ///
153    /// Supported formats:
154    /// * RFC3999 (ISO-8601) eg. 2018-02-15T05:15:00Z
155    /// * Simple date (yyyy-mm-dd) eg. 2018-02-15
156    /// * Unix timestamp (in seconds) eg. 1518671700
157    pub fn start(&mut self, start: &str) -> &'a mut GetHistoricalTicksRequest {
158        self.start = String::from(start);
159        self
160    }
161
162    /// End point for historical data
163    ///
164    /// Default: `"NOW"`
165    ///
166    /// Supported formats:
167    /// RFC3999 (ISO-8601) eg. 2018-02-15T05:15:00Z
168    /// Simple date (yyyy-mm-dd) eg. 2018-02-15
169    /// Unix timestamp (in seconds) eg. 1518671700
170    pub fn end(&mut self, end: &str) -> &'a mut GetHistoricalTicksRequest {
171        self.end = Some(String::from(end));
172        self
173    }
174
175    /// Limit of result rows (max `5000`)
176    ///
177    /// Default: `1000`
178    pub fn limit(&mut self, limit: i32) -> &'a mut GetHistoricalTicksRequest {
179        self.limit = Some(limit.to_string());
180        self
181    }
182
183    /// Returned data quote (available values: `usd` `btc`)
184    ///
185    /// Default: `"usd"`
186    pub fn quote(&mut self, quote: &str) -> &'a mut GetHistoricalTicksRequest {
187        self.quote = Some(String::from(quote));
188        self
189    }
190
191    /// Returned points interval (available values: `5m` `10m` `15m` `30m` `45m` `1h` `2h` `3h`
192    /// `6h` `12h` `24h` `1d` `7d` `14d` `30d` `90d` `365d`)
193    ///
194    /// Default: `"5m"`
195    pub fn interval(&mut self, interval: &str) -> &'a mut GetHistoricalTicksRequest {
196        self.interval = Some(String::from(interval));
197        self
198    }
199
200    pub async fn send(&self) -> Result<Vec<HistoricalTick>, Error> {
201        let mut query: Vec<(&str, &str)> = vec![("start", self.start.as_ref())];
202
203        if let Some(end) = &self.end {
204            query.push(("end", end));
205        }
206
207        if let Some(limit) = &self.limit {
208            query.push(("limit", limit));
209        }
210
211        if let Some(quote) = &self.quote {
212            query.push(("quote", quote));
213        }
214
215        if let Some(interval) = &self.interval {
216            query.push(("interval", interval));
217        }
218
219        let request: RequestBuilder = self
220            .client
221            .client
222            .get(format!(
223                "{}/tickers/{}/historical",
224                self.client.api_url, self.coin_id
225            ))
226            .query(&query);
227
228        let response: Response = self.client.request(request).await?;
229
230        let data: Vec<HistoricalTick> = response.response.json().await?;
231
232        Ok(data)
233    }
234}