Skip to main content

barter_data/exchange/gateio/
mod.rs

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