barter_data/exchange/gateio/
mod.rs

1use self::{channel::GateioChannel, market::GateioMarket, subscription::GateioSubResponse};
2use crate::{
3    exchange::{Connector, ExchangeServer, subscription::ExchangeSub},
4    subscriber::{WebSocketSubscriber, validator::WebSocketSubValidator},
5};
6use barter_instrument::exchange::ExchangeId;
7use barter_integration::{error::SocketError, protocol::websocket::WsMessage};
8use serde_json::json;
9use std::{fmt::Debug, marker::PhantomData};
10use url::Url;
11
12/// Defines the type that translates a Barter [`Subscription`](crate::subscription::Subscription)
13/// into an exchange [`Connector`] specific channel used for generating [`Connector::requests`].
14pub mod channel;
15
16/// [`ExchangeServer`] and [`StreamSelector`](super::StreamSelector) implementations for
17/// [`GateioSpot`](spot::GateioSpot).
18pub mod spot;
19
20/// [`ExchangeServer`] and [`StreamSelector`](super::StreamSelector) implementations for
21/// [`GateioFutureUsd`](future::GateioFuturesUsd) and
22/// [`GateioFutureBtc`](future::GateioFuturesBtc).
23pub mod future;
24
25/// [`ExchangeServer`] and [`StreamSelector`](super::StreamSelector) implementations for
26/// [`GateioPerpetualUsdt`](perpetual::GateioPerpetualsUsd) and
27/// [`GateioPerpetualBtc`](perpetual::GateioPerpetualsBtc).
28pub mod perpetual;
29
30/// [`ExchangeServer`] and [`StreamSelector`](super::StreamSelector) implementations for
31/// [`GateioOptions`](option::GateioOptions)
32pub mod option;
33
34/// Defines the type that translates a Barter [`Subscription`](crate::subscription::Subscription)
35/// into an exchange [`Connector`] specific market used for generating [`Connector::requests`].
36pub mod market;
37
38/// Generic [`GateioMessage<T>`](message::GateioMessage) type common to
39/// [`GateioSpot`](spot::GateioSpot), [`GateioPerpetualUsdt`](perpetual::GateioPerpetualsUsd)
40/// and [`GateioPerpetualBtc`](perpetual::GateioPerpetualsBtc).
41pub mod message;
42
43/// [`Subscription`](crate::subscription::Subscription) response type and response
44/// [`Validator`](barter_integration) common to [`GateioSpot`](spot::GateioSpot),
45/// [`GateioPerpetualUsdt`](perpetual::GateioPerpetualsUsd) and
46/// [`GateioPerpetualBtc`](perpetual::GateioPerpetualsBtc).
47pub mod subscription;
48
49/// Generic [`Gateio<Server>`](Gateio) exchange.
50///
51/// ### Notes
52/// A `Server` [`ExchangeServer`] implementations exists for
53/// [`GateioSpot`](spot::GateioSpot), [`GateioPerpetualUsdt`](perpetual::GateioPerpetualsUsd) and
54/// [`GateioPerpetualBtc`](perpetual::GateioPerpetualsBtc).
55#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
56pub struct Gateio<Server> {
57    server: PhantomData<Server>,
58}
59
60impl<Server> Connector for Gateio<Server>
61where
62    Server: ExchangeServer,
63{
64    const ID: ExchangeId = Server::ID;
65    type Channel = GateioChannel;
66    type Market = GateioMarket;
67    type Subscriber = WebSocketSubscriber;
68    type SubValidator = WebSocketSubValidator;
69    type SubResponse = GateioSubResponse;
70
71    fn url() -> Result<Url, SocketError> {
72        Url::parse(Server::websocket_url()).map_err(SocketError::UrlParse)
73    }
74
75    fn requests(exchange_subs: Vec<ExchangeSub<Self::Channel, Self::Market>>) -> Vec<WsMessage> {
76        exchange_subs
77            .into_iter()
78            .map(|ExchangeSub { channel, market }| {
79                WsMessage::text(
80                    json!({
81                        "time": chrono::Utc::now().timestamp_millis(),
82                        "channel": channel.as_ref(),
83                        "event": "subscribe",
84                        "payload": [market.as_ref()]
85                    })
86                    .to_string(),
87                )
88            })
89            .collect()
90    }
91}
92
93impl<'de, Server> serde::Deserialize<'de> for Gateio<Server>
94where
95    Server: ExchangeServer,
96{
97    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98    where
99        D: serde::de::Deserializer<'de>,
100    {
101        let input = <String as serde::Deserialize>::deserialize(deserializer)?;
102        if input.as_str() == Self::ID.as_str() {
103            Ok(Self::default())
104        } else {
105            Err(serde::de::Error::invalid_value(
106                serde::de::Unexpected::Str(input.as_str()),
107                &Self::ID.as_str(),
108            ))
109        }
110    }
111}
112
113impl<Server> serde::Serialize for Gateio<Server>
114where
115    Server: ExchangeServer,
116{
117    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
118    where
119        S: serde::ser::Serializer,
120    {
121        serializer.serialize_str(Self::ID.as_str())
122    }
123}