binance-api 0.1.0

Yet another async Binance API
Documentation
#![allow(dead_code)]
use std::error::Error;

use binance_api::{url_query, Client, Config, FuturesApi, SpotApi};

#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct Timestamp {
    server_time: u64,
}

#[derive(Debug, serde::Deserialize)]
#[serde(try_from = "[String; 2]")]
struct Level {
    price: f64,
    qty: f64,
}

impl TryFrom<[String; 2]> for Level {
    type Error = String;

    fn try_from([price, qty]: [String; 2]) -> Result<Self, Self::Error> {
        let price = price
            .parse()
            .map_err(|_| "Cannot convert price".to_string())?;
        let qty = qty
            .parse()
            .map_err(|_| "Cannot convert price".to_string())?;
        Ok(Self { price, qty })
    }
}

#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct OrderBook {
    last_update_id: u64,
    bids: Vec<Level>,
    asks: Vec<Level>,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let config = Config::default();
    let client = Client::new(config.spot.rest_api, None);

    let data: Timestamp = client.request(&SpotApi::CheckServerTime, &[]).await?;
    println!("Server Time is: {:?}", data);

    let ob: OrderBook = client
        .request(
            &SpotApi::OrderBook,
            &url_query!(symbol = "BTCUSDT", limit = 1),
        )
        .await?;
    println!("BTCUSDT (spot) spread is: {:#?}", ob);

    let client = Client::new(config.futures.rest_api, None);
    let ob: OrderBook = client
        .request(
            &FuturesApi::OrderBook,
            &url_query!(symbol = "ETHUSDT", limit = 5),
        )
        .await?;
    println!("ETHUSDT (futures) orderbook is: {:#?}", ob);
    Ok(())
}