use polyoxide_core::HttpClient;
use crate::spot::{
error::SpotError,
request::{route_builder, Routed},
types::{
AggTrade, AvgPrice, BookTicker, Depth, Interval, Kline, PriceTicker, Symbol, Ticker24h,
Trade,
},
weight::{Cost, Route},
};
#[derive(Debug, Clone)]
pub struct MarketApi {
pub(crate) http: HttpClient,
}
impl MarketApi {
fn request<T>(&self, route: Route) -> Routed<T> {
Routed::new(&self.http, route)
}
pub fn depth(&self, symbol: &Symbol) -> GetDepth {
GetDepth {
request: self
.request(Route::Depth { limit: None })
.query("symbol", symbol),
}
}
pub fn trades(&self, symbol: &Symbol) -> GetTrades {
GetTrades {
request: self.request(Route::Trades).query("symbol", symbol),
}
}
pub fn agg_trades(&self, symbol: &Symbol) -> GetAggTrades {
GetAggTrades {
request: self.request(Route::AggTrades).query("symbol", symbol),
}
}
pub fn klines(&self, symbol: &Symbol, interval: Interval) -> GetKlines {
GetKlines {
request: self
.request(Route::Klines)
.query("symbol", symbol)
.query("interval", interval),
}
}
pub fn avg_price(&self, symbol: &Symbol) -> GetAvgPrice {
GetAvgPrice {
request: self.request(Route::AvgPrice).query("symbol", symbol),
}
}
pub fn ticker_24h(&self, symbol: &Symbol) -> GetTicker24h {
GetTicker24h {
request: self
.request(Route::Ticker24h { all: false })
.query("symbol", symbol),
}
}
pub fn tickers_24h(&self) -> GetTickers24h {
GetTickers24h {
request: self.request(Route::Ticker24h { all: true }),
}
}
pub fn price(&self, symbol: &Symbol) -> GetPrice {
GetPrice {
request: self
.request(Route::Price { all: false })
.query("symbol", symbol),
}
}
pub fn prices(&self) -> GetPrices {
GetPrices {
request: self.request(Route::Price { all: true }),
}
}
pub fn book_ticker(&self, symbol: &Symbol) -> GetBookTicker {
GetBookTicker {
request: self
.request(Route::BookTicker { all: false })
.query("symbol", symbol),
}
}
pub fn book_tickers(&self) -> GetBookTickers {
GetBookTickers {
request: self.request(Route::BookTicker { all: true }),
}
}
}
route_builder! {
GetAvgPrice => AvgPrice
}
route_builder! {
GetTicker24h => Ticker24h
}
route_builder! {
GetTickers24h => Vec<Ticker24h>
}
route_builder! {
GetPrice => PriceTicker
}
route_builder! {
GetPrices => Vec<PriceTicker>
}
route_builder! {
GetBookTicker => BookTicker
}
route_builder! {
GetBookTickers => Vec<BookTicker>
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetDepth {
request: Routed<Depth>,
}
impl GetDepth {
pub fn limit(mut self, limit: u32) -> Self {
self.request = self
.request
.route(Route::Depth { limit: Some(limit) })
.query("limit", limit);
self
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Depth, SpotError> {
self.request.send().await
}
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetTrades {
request: Routed<Vec<Trade>>,
}
impl GetTrades {
polyoxide_core::query_setters! {
limit: u32 => "limit",
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Vec<Trade>, SpotError> {
self.request.send().await
}
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetAggTrades {
request: Routed<Vec<AggTrade>>,
}
impl GetAggTrades {
polyoxide_core::query_setters! {
from_id: u64 => "fromId",
start_time: u64 => "startTime",
end_time: u64 => "endTime",
limit: u32 => "limit",
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Vec<AggTrade>, SpotError> {
self.request.send().await
}
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetKlines {
request: Routed<Vec<Kline>>,
}
impl GetKlines {
polyoxide_core::query_setters! {
start_time: u64 => "startTime",
end_time: u64 => "endTime",
limit: u32 => "limit",
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Vec<Kline>, SpotError> {
self.request.send().await
}
}