use crate::{
types::{CurrencyInfo, MarketInfo, MarketSummary, Order, OrderBook, TickerInfo},
ApiResult, Client, API_URL,
};
use anyhow::{anyhow, Result};
use once_cell::sync::Lazy;
impl Client {
pub fn get_markets() -> Result<Vec<MarketInfo>> {
static URL: Lazy<String> = Lazy::new(|| API_URL.to_string() + "/public/getmarkets");
let response = ureq::get(&URL).call();
let result: ApiResult<Vec<MarketInfo>> = response.into_json_deserialize()?;
result.into_result()
}
pub fn get_currencies() -> Result<Vec<CurrencyInfo>> {
static URL: Lazy<String> = Lazy::new(|| API_URL.to_string() + "/public/getcurrencies");
let response = ureq::get(&URL).call();
let result: ApiResult<Vec<CurrencyInfo>> = response.into_json_deserialize()?;
result.into_result()
}
pub fn get_ticker<S: AsRef<str>>(market: S) -> Result<TickerInfo> {
static URL: Lazy<String> = Lazy::new(|| API_URL.to_string() + "/public/getticker");
let mut req = ureq::get(&URL);
let _ = req.query("market", market.as_ref());
let response = req.call();
let result: ApiResult<TickerInfo> = response.into_json_deserialize()?;
result.into_result()
}
pub fn get_market_summaries() -> Result<Vec<MarketSummary>> {
static URL: Lazy<String> = Lazy::new(|| API_URL.to_string() + "/public/getmarketsummaries");
let response = ureq::get(&URL).call();
let result: ApiResult<Vec<MarketSummary>> = response.into_json_deserialize()?;
result.into_result()
}
pub fn get_market_summary<S: AsRef<str>>(market: S) -> Result<MarketSummary> {
static URL: Lazy<String> = Lazy::new(|| API_URL.to_string() + "/public/getmarketsummary");
let mut req = ureq::get(&URL);
let _ = req.query("market", market.as_ref());
let response = req.call();
let result: ApiResult<Vec<MarketSummary>> = response.into_json_deserialize()?;
result.into_result().and_then(|arr| {
arr.into_iter()
.next()
.ok_or_else(|| anyhow!("api response did not contain the market summary"))
})
}
pub fn get_order_book<S: AsRef<str>>(
market: S,
order_type: OrderBookType,
depth: u8,
) -> Result<OrderBook> {
static URL: Lazy<String> = Lazy::new(|| API_URL.to_string() + "/public/getorderbook");
assert!(depth <= 50, "order book depth must be between 0 and 50");
let mut req = ureq::get(&URL);
let _ = req
.query("market", market.as_ref())
.query("type", order_type.as_str())
.query("depth", &depth.to_string());
let response = req.call();
match order_type {
OrderBookType::Buy => {
let result: ApiResult<Box<[Order]>> = response.into_json_deserialize()?;
Ok(OrderBook::new(result.into_result()?, Vec::new()))
}
OrderBookType::Sell => {
let result: ApiResult<Box<[Order]>> = response.into_json_deserialize()?;
Ok(OrderBook::new(Vec::new(), result.into_result()?))
}
OrderBookType::Both => {
let result: ApiResult<OrderBook> = response.into_json_deserialize()?;
result.into_result()
}
}
}
pub fn get_market_history<S: AsRef<str>>(market: S) -> Result<MarketSummary> {
static URL: Lazy<String> = Lazy::new(|| API_URL.to_string() + "/public/getmarketsummary");
let mut req = ureq::get(&URL);
let _ = req.query("market", market.as_ref());
let response = req.call();
let result: ApiResult<Vec<MarketSummary>> = response.into_json_deserialize()?;
result.into_result().and_then(|arr| {
arr.into_iter()
.next()
.ok_or_else(|| anyhow!("api response did not contain the market summary"))
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OrderBookType {
Buy,
Sell,
Both,
}
impl OrderBookType {
fn as_str(&self) -> &str {
match self {
Self::Buy => "buy",
Self::Sell => "sell",
Self::Both => "both",
}
}
}