use log::info;
use serde::ser::Error;
use serde_json::Value;
use crate::futures_usd::enums::events::Event;
use crate::futures_usd::enums::events::Event::*;
use crate::futures_usd::enums::events::EventType::*;
use crate::futures_usd::response::{
AssetIndexUpdate, AssetIndexUpdates, BookTicker, BookTickers, EventTypeWrapper,
MarkPriceUpdate, MarkPriceUpdates, MiniTicker, MiniTickers, SubscribeResponse, Ticker, Tickers,
};
pub fn deserialize(json_response: String) -> Result<Event, serde_json::Error> {
if let Some(result) = try_deserialize_event_type_wrapper(&json_response) {
return result;
}
if let Some(result) = try_deserialize_subscribe_response(&json_response) {
return result;
}
if let Some(result) = try_deserialize_anonymous_array(&json_response) {
return result;
}
Err(serde_json::Error::custom(format!(
"No deserializer for {:?}",
json_response
)))
}
fn try_deserialize_event_type_wrapper(
json_response: &str,
) -> Option<Result<Event, serde_json::Error>> {
if let Ok(event_type_wrapper) = serde_json::from_str::<EventTypeWrapper>(json_response) {
return Some(match event_type_wrapper.event_type {
BookTickerEventType => Ok(BookTickerEvent(
serde_json::from_str(json_response).unwrap(),
)),
AggTradeEventType => Ok(AggTradeEvent(serde_json::from_str(json_response).unwrap())),
MarkPriceUpdateEventType => Ok(MarkPriceUpdateEvent(
serde_json::from_str(json_response).unwrap(),
)),
KlineEventType => Ok(KlineEvent(serde_json::from_str(json_response).unwrap())),
ContinuousKlineEventType => Ok(ContinuousKlineEvent(
serde_json::from_str(json_response).unwrap(),
)),
MiniTickerEventType => Ok(MiniTickerEvent(
serde_json::from_str(json_response).unwrap(),
)),
TickerEventType => Ok(TickerEvent(serde_json::from_str(json_response).unwrap())),
ForceOrderEventType => Ok(ForceOrderEvent(
serde_json::from_str(json_response).unwrap(),
)),
BookDepthEventType => Ok(BookDepthEvent(serde_json::from_str(json_response).unwrap())),
CompositeIndexEventType => Ok(CompositeIndexEvent(
serde_json::from_str(json_response).unwrap(),
)),
ContractInfoEventType => Ok(ContractInfoEvent(
serde_json::from_str(json_response).unwrap(),
)),
AssetIndexUpdateEventType => Ok(AssetIndexUpdateEvent(
serde_json::from_str(json_response).unwrap(),
)),
AccountUpdateEventType => Ok(AccountUpdateEvent(
serde_json::from_str(json_response).unwrap(),
)),
OrderTradeUpdateEventType => Ok(OrderTradeUpdateEvent(
serde_json::from_str(json_response).unwrap(),
)),
MarginCallEventType => Ok(MarginCallEvent(
serde_json::from_str(json_response).unwrap(),
)),
AccountConfigUpdateEventType => Ok(AccountConfigUpdateEvent(
serde_json::from_str(json_response).unwrap(),
)),
StrategyUpdateEventType => Ok(StrategyUpdateEvent(
serde_json::from_str(json_response).unwrap(),
)),
GridUpdateEventType => Ok(GridUpdateEvent(
serde_json::from_str(json_response).unwrap(),
)),
ConditionalOrderTriggerRejectEventType => Ok(ConditionalOrderTriggerRejectEvent(
serde_json::from_str(json_response).unwrap(),
)),
});
}
None
}
fn try_deserialize_subscribe_response(
json_response: &String,
) -> Option<Result<Event, serde_json::Error>> {
if let Ok(subscribe_response) = serde_json::from_str::<SubscribeResponse>(&json_response) {
if let Some(id) = subscribe_response.id {
info!("futures_usd subscription request received ({})", id);
}
return Some(Ok(SubscribeResponseEvent));
}
None
}
fn try_deserialize_anonymous_array(
json_response: &String,
) -> Option<Result<Event, serde_json::Error>> {
let value: Value = serde_json::from_str(json_response).map_err(Some).ok()?;
if let Some(arr) = value.as_array() {
if let Some(first_item) = arr.get(0) {
if let Ok(event_type_wrapper) =
serde_json::from_value::<EventTypeWrapper>(first_item.clone())
{
match event_type_wrapper.event_type {
MarkPriceUpdateEventType => {
let market_price_updates: Vec<MarkPriceUpdate> = arr
.iter()
.map(|item| serde_json::from_value(item.clone()).unwrap())
.collect();
return Some(Ok(MarkPriceUpdatesEvent(MarkPriceUpdates {
data: market_price_updates,
})));
}
MiniTickerEventType => {
let mini_tickers: Vec<MiniTicker> = arr
.iter()
.map(|item| serde_json::from_value(item.clone()).unwrap())
.collect();
return Some(Ok(MiniTickersEvent(MiniTickers { data: mini_tickers })));
}
TickerEventType => {
let tickers: Vec<Ticker> = arr
.iter()
.map(|item| serde_json::from_value(item.clone()).unwrap())
.collect();
return Some(Ok(TickersEvent(Tickers { data: tickers })));
}
BookTickerEventType => {
let book_tickers: Vec<BookTicker> = arr
.iter()
.map(|item| serde_json::from_value(item.clone()).unwrap())
.collect();
return Some(Ok(BookTickersEvent(BookTickers { data: book_tickers })));
}
AssetIndexUpdateEventType => {
let asset_index_updates: Vec<AssetIndexUpdate> = arr
.iter()
.map(|item| serde_json::from_value(item.clone()).unwrap())
.collect();
return Some(Ok(AssetIndexUpdatesEvent(AssetIndexUpdates {
data: asset_index_updates,
})));
}
_ => {}
}
}
}
}
None
}