use rust_decimal::Decimal;
use rust_decimal::prelude::{FromPrimitive, FromStr};
use serde_json::Value;
use std::collections::HashMap;
pub use balance::{parse_balance, parse_balance_with_type};
pub use funding::{parse_funding_rate, parse_funding_rate_history};
pub use margin::{parse_margin_adjustment, parse_margin_loan};
pub use market::{parse_currencies, parse_market};
pub use misc::{
parse_mark_prices, parse_stats_24hr, parse_trading_fee, parse_trading_limits,
parse_ws_mark_price,
};
pub use ohlcv::{parse_ohlcvs, parse_ws_ohlcv};
pub use order::parse_order;
pub use orderbook::{parse_orderbook, parse_ws_orderbook};
pub use position::{parse_leverage, parse_leverage_tier, parse_position};
pub use ticker::{
parse_bids_asks, parse_last_prices, parse_ticker, parse_ws_bid_ask, parse_ws_ticker,
};
pub use trade::{parse_agg_trade, parse_trade, parse_ws_trade};
pub use transaction::{parse_deposit_address, parse_deposit_withdraw_fees, parse_transaction};
mod balance;
mod funding;
mod margin;
mod market;
mod misc;
mod ohlcv;
mod order;
mod orderbook;
mod position;
mod ticker;
mod trade;
mod transaction;
pub(crate) fn parse_f64(data: &Value, key: &str) -> Option<f64> {
data.get(key).and_then(|v| {
v.as_f64()
.or_else(|| v.as_str().and_then(|s| s.parse::<f64>().ok()))
})
}
pub(crate) fn parse_decimal(data: &Value, key: &str) -> Option<Decimal> {
data.get(key).and_then(|v| {
if let Some(s) = v.as_str() {
Decimal::from_str(s).ok()
} else if let Some(num) = v.as_f64() {
Decimal::from_f64(num)
} else {
None
}
})
}
pub(crate) fn parse_decimal_multi(data: &Value, keys: &[&str]) -> Option<Decimal> {
for key in keys {
if let Some(decimal) = parse_decimal(data, key) {
return Some(decimal);
}
}
None
}
pub(crate) fn value_to_hashmap(data: &Value) -> HashMap<String, Value> {
data.as_object()
.map(|obj| obj.iter().map(|(k, v)| (k.clone(), v.clone())).collect())
.unwrap_or_default()
}
#[allow(dead_code)]
pub(crate) fn parse_order_book_entries(data: &Value) -> Vec<ccxt_core::types::OrderBookEntry> {
use ccxt_core::types::{
OrderBookEntry,
financial::{Amount, Price},
};
data.as_array()
.map(|arr| {
arr.iter()
.filter_map(|item| {
let price = if let Some(arr) = item.as_array() {
arr.first()
.and_then(serde_json::Value::as_str)
.and_then(|s| Decimal::from_str(s).ok())
} else {
None
}?;
let amount = if let Some(arr) = item.as_array() {
arr.get(1)
.and_then(serde_json::Value::as_str)
.and_then(|s| Decimal::from_str(s).ok())
} else {
None
}?;
Some(OrderBookEntry {
price: Price::new(price),
amount: Amount::new(amount),
})
})
.collect()
})
.unwrap_or_default()
}