1use reqwest::StatusCode;
2use serde::Deserialize;
3use serde_json::Value;
4
5use crate::{client::Client, EasyBit, Error};
6
7#[derive(Deserialize, Debug, Clone)]
8#[allow(non_snake_case)]
9pub struct Currency {
19 pub currency: String,
20 pub name: String,
21 pub sendStatusAll: bool,
22 pub receiveStatusAll: bool,
23 pub networkList: Vec<Network>,
24}
25
26#[derive(Deserialize, Debug, Clone)]
27#[allow(non_snake_case)]
28pub struct Network {
46 pub network: String,
47 pub name: String,
48 pub isDefault: bool,
49 pub sendStatus: bool,
50 pub receiveStatus: bool,
51 pub receiveDecimals: i32,
52 pub confirmationsMinimum: i32,
53 pub confirmationsMaximum: i32,
54 pub explorer: String,
55 pub explorerHash: String,
56 pub explorerAddress: String,
57 pub hasTag: bool,
58 pub tagName: Option<String>,
59 pub contractAddress: Option<String>,
60 pub explorerContract: Option<String>,
61}
62
63pub async fn get_currency_list(client: &Client) -> Result<Vec<Currency>, Error> {
64 let path = "/currencyList";
66
67 let response = reqwest::Client::new()
69 .get(format!("{}{}", client.get_url(), path))
70 .header("API-KEY", client.get_api_key())
71 .send()
72 .await?;
73
74 let json: Value = response.json().await?;
75 match json.get("data") {
76 Some(data) => {
77 let currency_list: Vec<Currency> = serde_json::from_value(data.clone())?;
78 Ok(currency_list)
79 }
80 None => {
81 let error: EasyBit = serde_json::from_value(json)?;
82 log::error!("{:?}", error);
83 Err(Error::ApiError(error))
84 }
85 }
86}
87
88pub async fn get_single_currency(client: &Client, currency: String) -> Result<Currency, Error> {
89 let path = format!("/currencyList?currency={}", currency);
91
92 let response = reqwest::Client::new()
94 .get(format!("{}{}", client.get_url(), path))
95 .header("API-KEY", client.get_api_key())
96 .send()
97 .await?;
98
99 match response.status() {
100 StatusCode::OK => {
101 let json: Value = response.json().await?;
103 match json.get("data") {
104 Some(data) => {
105 let currency: Vec<Currency> = serde_json::from_value(data.clone())?;
107
108 if currency.is_empty() {
109 return Err(Error::ApiError(EasyBit {
110 errorMessage: "Currency not found".to_string(),
111 errorCode: 404,
112 }));
113 }
114 Ok(currency[0].clone())
115 }
116 None => {
117 let error: EasyBit = serde_json::from_value(json)?;
118 log::error!("{:?}", error);
119 Err(Error::ApiError(error))
120 }
121 }
122 }
123 _ => {
124 let error: EasyBit = response.json().await?;
125 log::error!("{:?}", error);
126 Err(Error::ApiError(error))
127 }
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use crate::client::Client;
135 use std::env;
136
137 #[tokio::test]
138 async fn test_get_currency_list() {
139 let client = Client::new(env::var("URL").unwrap(), env::var("API_KEY").unwrap());
140 let currency_list = get_currency_list(&client).await.unwrap();
141
142 for currency in currency_list.iter().take(1) {
144 println!("{:?}", currency);
145 }
146
147 assert!(currency_list.len() > 0);
148 }
149
150 #[tokio::test]
151 async fn test_get_single_currency() {
152 let client = Client::new(env::var("URL").unwrap(), env::var("API_KEY").unwrap());
153 let currency = get_single_currency(&client, "BTC".to_string())
154 .await
155 .unwrap();
156 println!("{:?}", currency);
157 assert_eq!(currency.currency, "BTC");
158 }
159}