use std::sync::Arc;
use crate::connector_manager::{ConnectorFactory, ConnectorPool, WebSocketPool};
use crate::core::traits::{CoreConnector, WebSocketConnector};
use crate::core::types::{AccountType, ConnectorCapabilities, ExchangeId, ExchangeResult};
#[derive(Clone, Default)]
pub struct ExchangeHub {
rest: ConnectorPool,
ws: WebSocketPool,
}
impl ExchangeHub {
pub fn new() -> Self {
Self::default()
}
pub async fn connect_public(&self, id: ExchangeId, testnet: bool) -> ExchangeResult<()> {
let conn = ConnectorFactory::create_public(id, testnet).await?;
self.rest.insert(id, conn);
Ok(())
}
pub fn rest(&self, id: ExchangeId) -> Option<Arc<dyn CoreConnector>> {
self.rest.get(&id)
}
pub async fn connect_websocket(
&self,
id: ExchangeId,
account_type: AccountType,
testnet: bool,
) -> ExchangeResult<()> {
let ws = ConnectorFactory::create_websocket(id, account_type, testnet).await?;
self.ws.insert(id, account_type, ws);
Ok(())
}
pub fn ws(&self, id: ExchangeId, account_type: AccountType) -> Option<Arc<dyn WebSocketConnector>> {
self.ws.get(id, account_type)
}
pub async fn connect_full(
&self,
id: ExchangeId,
account_types: &[AccountType],
testnet: bool,
) -> ExchangeResult<()> {
let conn = ConnectorFactory::create_public(id, testnet).await?;
self.rest.insert(id, conn);
for &at in account_types {
if let Ok(ws) = ConnectorFactory::create_websocket(id, at, testnet).await {
self.ws.insert(id, at, ws);
}
}
Ok(())
}
pub fn capabilities(&self, id: ExchangeId) -> Option<ConnectorCapabilities> {
self.rest.get(&id).map(|c| c.capabilities())
}
pub fn ids(&self) -> Vec<ExchangeId> {
self.rest.ids()
}
pub fn len_rest(&self) -> usize {
self.rest.len()
}
pub fn len_ws(&self) -> usize {
self.ws.len()
}
pub fn len(&self) -> usize {
self.rest.len() + self.ws.len()
}
pub fn is_empty(&self) -> bool {
self.rest.is_empty() && self.ws.is_empty()
}
pub fn shutdown(&self, id: ExchangeId) {
self.rest.remove(&id);
for at in [
AccountType::Spot,
AccountType::Margin,
AccountType::FuturesCross,
AccountType::FuturesIsolated,
AccountType::Earn,
AccountType::Lending,
AccountType::Options,
AccountType::Convert,
] {
self.ws.remove(id, at);
}
}
pub fn clear(&self) {
self.rest.clear();
self.ws.clear();
}
pub fn rest_pool(&self) -> &ConnectorPool {
&self.rest
}
pub fn ws_pool(&self) -> &WebSocketPool {
&self.ws
}
}