switchboard_utils/exchanges/
huobi.rs

1use crate::*;
2
3use futures_util::TryFutureExt;
4
5use serde::Deserialize;
6
7#[allow(dead_code)]
8#[derive(Debug, Deserialize, Clone)]
9struct HuobiMarketData {
10    pub ch: String,
11    pub status: String,
12    pub ts: i64,
13    pub tick: HuobiTickerInfo,
14}
15
16#[derive(Debug, Clone, Deserialize)]
17pub struct HuobiTickerInfo {
18    pub id: i64,
19    pub version: i64,
20    pub open: f64,
21    pub close: f64,
22    pub low: f64,
23    pub high: f64,
24    pub amount: f64,
25    pub vol: f64,
26    pub count: i64,
27    pub bid: (f64, f64),
28    pub ask: (f64, f64),
29}
30
31pub struct HuobiApi {}
32
33impl HuobiApi {
34    // https://api.huobi.pro/market/detail/merged?symbol=btcusdt
35    fn get_ticker_url(ticker: &str, url: Option<&str>) -> String {
36        format!(
37            "{}/market/detail/merged?symbol={}",
38            url.unwrap_or("https://api.huobi.pro"),
39            ticker
40        )
41    }
42
43    pub async fn fetch_ticker(ticker: &str, url: Option<&str>) -> Result<HuobiTickerInfo, SbError> {
44        let ticker_url = HuobiApi::get_ticker_url(ticker, url);
45
46        let response: HuobiMarketData = reqwest::get(&ticker_url)
47            .and_then(|r| r.json())
48            .await
49            .map_err(handle_reqwest_err)?;
50
51        Ok(response.tick)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    const MOCK_HUOBI_RESPONSE: &str = r#"{"ch":"market.btcusdt.detail.merged","status":"ok","ts":1696450585149,"tick":{"id":330331957961,"version":330331957961,"open":27346.88,"close":27703.8,"low":27204.95,"high":27835.9,"amount":4105.804118401724,"vol":1.1280903302844201E8,"count":557808,"bid":[27699.26,1.218876],"ask":[27699.27,0.32722]}}"#;
60
61    #[tokio::test]
62    async fn test_huobi_api() {
63        // Request a new server from the pool
64        let mut server = mockito::Server::new();
65        let server_url = server.url();
66
67        // Create a mock
68        let _mock = server
69            .mock("GET", "/market/detail/merged?symbol=btcusdt")
70            .with_status(201)
71            .with_header("content-type", "application/json")
72            .with_body(MOCK_HUOBI_RESPONSE)
73            .create();
74
75        let _ticker = HuobiApi::fetch_ticker("btcusdt", Some(server_url.as_str()))
76            .await
77            .unwrap();
78        // TODO: fix test
79        // println!("{:?}", ticker);
80
81        // verify the mock was called
82        // mock.assert();
83        //
84        // assert_eq!(ticker.open, 27346.88);
85    }
86}