easybit/currency/
info.rs

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)]
9/**
10    ### Currency information.
11    
12    - `currency`: Currency code
13    - `name`: Currency name
14    - `sendStatusAll`: If the system can send this currency through at least one network
15    - `receiveStatusAll`: If the system can receive this currency through at least one network
16    - `networkList`: List of networks
17*/
18pub 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)]
28/**
29    - `network`: Network code
30    - `name`: Network name
31    - `isDefault`: If the network is the default network
32    - `sendStatus`: If the system can send through this network
33    - `receiveStatus`: If the system can receive through this network
34    - `receiveDecimals`: Number of decimals for the currency
35    - `confirmationsMinimum`: Minimum number of confirmations required
36    - `confirmationsMaximum`: Maximum number of confirmations required
37    - `explorer`: URL for the explorer
38    - `explorerHash`: URL for the hash explorer
39    - `explorerAddress`: URL for the address explorer
40    - `hasTag`: If the network requires a tag
41    - `tagName`: Name of the tag
42    - `contractAddress`: Contract address for the network
43    - `explorerContract`: URL for the contract explorer
44*/
45pub 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    // Define the URL.
65    let path = "/currencyList";
66
67    // Make the request and set API key.
68    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    // Define the URL with the currency as a query parameter.
90    let path = format!("/currencyList?currency={}", currency);
91
92    // Make the request and set API key.
93    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            // Convert the response to an object. Do not use unwrap.
102            let json: Value = response.json().await?;
103            match json.get("data") {
104                Some(data) => {
105                    // Print the data.
106                    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        // Print the first three currencies.
143        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}