use super::{midpoint, AskBook, BidBook};
use crate::{
config::HttpsConfig, prelude::*, Currency, Error, ErrorKind, Price, PriceQuantity, TradingPair,
};
use iqhttp::{HttpsClient, Query};
use serde::{Deserialize, Serialize};
pub const API_HOST: &str = "api.coinone.co.kr";
pub struct CoinoneSource {
https_client: HttpsClient,
}
impl CoinoneSource {
pub fn new(config: &HttpsConfig) -> Result<Self, Error> {
let https_client = config.new_client(API_HOST)?;
Ok(Self { https_client })
}
pub async fn trading_pairs(&self, pair: &TradingPair) -> Result<Price, Error> {
if pair.1 != Currency::Krw {
fail!(ErrorKind::Currency, "trading pair must be with KRW");
}
let mut query = Query::new();
query.add("currency".to_owned(), pair.0.to_string());
let api_response: Response = self.https_client.get_json("/orderbook", &query).await?;
midpoint(&api_response)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Response {
#[serde(rename = "errorCode")]
pub error_code: String,
pub result: String,
pub currency: String,
pub timestamp: String,
pub ask: Vec<PricePoint>,
pub bid: Vec<PricePoint>,
}
impl AskBook for Response {
fn asks(&self) -> Result<Vec<PriceQuantity>, Error> {
self.ask
.iter()
.map(|p| {
p.qty
.parse()
.map(|quantity| PriceQuantity {
price: p.price,
quantity,
})
.map_err(Into::into)
})
.collect()
}
}
impl BidBook for Response {
fn bids(&self) -> Result<Vec<PriceQuantity>, Error> {
self.bid
.iter()
.map(|p| {
p.qty
.parse()
.map(|quantity| PriceQuantity {
price: p.price,
quantity,
})
.map_err(Into::into)
})
.collect()
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PricePoint {
pub price: Price,
pub qty: String,
}
#[cfg(test)]
mod tests {
use super::CoinoneSource;
#[tokio::test]
#[ignore]
async fn trading_pairs_ok() {
let pair = "LUNA/KRW".parse().unwrap();
let _price = CoinoneSource::new(&Default::default())
.unwrap()
.trading_pairs(&pair)
.await
.unwrap();
}
#[tokio::test]
#[ignore]
async fn trading_pairs_404() {
let pair = "N/A".parse().unwrap();
let _err = CoinoneSource::new(&Default::default())
.unwrap()
.trading_pairs(&pair)
.await
.err()
.unwrap();
}
}