1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! Binance exchange public API client.

pub mod parse;

use std::convert::TryFrom;

use async_trait::async_trait;

use cxmr_api_clients_errors::Error;
use cxmr_exchanges::{Exchange, ExchangeInfo};
use cxmr_http_client::{build_request, send_request, BufExt, HttpsClient};

use self::parse::BncExchangeInfo;

pub static BINANCE_HOST: &'static str = "www.binance.com";

/// Binance API client struct.
#[derive(Clone)]
pub struct PublicClient {
    client: HttpsClient,
}

impl PublicClient {
    pub fn new(client: HttpsClient) -> Self {
        PublicClient { client: client }
    }
}

#[async_trait]
impl cxmr_api::PublicClient for PublicClient {
    type Error = Error;

    fn exchange(&self) -> &'static Exchange {
        &Exchange::Binance
    }

    async fn exchange_info(&self) -> Result<ExchangeInfo, Self::Error> {
        let req = build_request(BINANCE_HOST, "/api/v1/exchangeInfo", None)?;
        let body = send_request(&self.client, req).await?;
        // trace!("Binance exchange info: {}", String::from_utf8_lossy(body.bytes()).to_string());
        let account: BncExchangeInfo = serde_json::from_reader(body.reader())?;
        Ok(ExchangeInfo::try_from(account)?)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    use tokio::runtime::Runtime;

    use cxmr_http_client::build_https_client;

    #[test]
    fn not_found_error() {
        let http_client = build_https_client().unwrap();
        let mut runtime = Runtime::new().unwrap();
        let req = build_request(BINANCE_HOST, "/api/v1/exchaneInfo", None).unwrap();
        let resp = runtime.block_on(send_request(&http_client, req));
        match resp {
            Ok(_) => panic!("unexpected response"),
            Err(cxmr_http_client::Error::Response(cxmr_http_client::ErrorResponse {
                status,
                ..
            })) => assert_eq!(status, 404),
            Err(e) => panic!("unexpecter error: {:?}", e),
        }
    }
}