rusty_feeder/exchange/bybit/data/
subscription.rs

1use serde::{Deserialize, Serialize};
2use smallvec::SmallVec;
3use smartstring::alias::String;
4
5// Serde support for SmallVec
6mod smallvec_serde {
7    use serde::{Deserialize, Deserializer, Serialize, Serializer};
8    use smallvec::SmallVec;
9
10    // Serialize SmallVec as a Vec
11    pub fn serialize<S, T>(small_vec: &SmallVec<[T; 4]>, serializer: S) -> Result<S::Ok, S::Error>
12    where
13        S: Serializer,
14        T: Serialize,
15    {
16        small_vec.as_slice().serialize(serializer)
17    }
18
19    // Deserialize SmallVec from a Vec
20    pub fn deserialize<'de, D, T>(deserializer: D) -> Result<SmallVec<[T; 4]>, D::Error>
21    where
22        D: Deserializer<'de>,
23        T: Deserialize<'de>,
24    {
25        let items = Vec::<T>::deserialize(deserializer)?;
26        Ok(SmallVec::from_vec(items))
27    }
28}
29
30/// Bybit WebSocket subscription request
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct SubscriptionRequest {
33    /// Operation type ("subscribe")
34    pub op: String,
35    /// List of topics to subscribe to
36    #[serde(with = "smallvec_serde")]
37    pub args: SmallVec<[String; 4]>,
38}
39
40impl SubscriptionRequest {
41    /// Create a new subscription request
42    #[must_use]
43    pub fn new(topics: SmallVec<[String; 4]>) -> Self {
44        Self {
45            op: "subscribe".into(),
46            args: topics,
47        }
48    }
49
50    /// Create a trade subscription for specific symbols
51    #[must_use]
52    pub fn trades(symbols: Vec<String>) -> Self {
53        let topics = symbols
54            .into_iter()
55            .map(|symbol| format!("publicTrade.{symbol}").into())
56            .collect();
57
58        Self::new(topics)
59    }
60
61    /// Create an orderbook subscription for specific symbols
62    #[must_use]
63    pub fn orderbook(symbols: Vec<String>, depth: u8) -> Self {
64        let topics = symbols
65            .into_iter()
66            .map(|symbol| format!("orderbook.{depth}.{symbol}").into())
67            .collect();
68
69        Self::new(topics)
70    }
71}
72
73/// Bybit WebSocket unsubscribe request
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct UnsubscribeRequest {
76    /// Operation type ("unsubscribe")
77    pub op: String,
78    /// List of topics to unsubscribe from
79    #[serde(with = "smallvec_serde")]
80    pub args: SmallVec<[String; 4]>,
81}
82
83impl UnsubscribeRequest {
84    /// Create a new unsubscribe request
85    #[must_use]
86    pub fn new(topics: SmallVec<[String; 4]>) -> Self {
87        Self {
88            op: "unsubscribe".into(),
89            args: topics,
90        }
91    }
92}
93
94/// Bybit WebSocket subscription response
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct SubscriptionResponse {
97    /// Whether the subscription was successful
98    pub success: bool,
99    /// Response message from the server
100    pub ret_msg: String,
101    /// Connection identifier
102    pub conn_id: String,
103    /// Operation type that was performed
104    pub op: String,
105}