Skip to main content

bybit/ws/
future.rs

1use super::callback::Callback;
2use super::response::FuturePublicResponseArg;
3use super::run;
4use super::Subscriber;
5use crate::error::Result;
6use crate::{FutureRole, KlineInterval};
7
8const MAINNET_LINEAR: &str = "wss://stream.bybit.com/v5/public/linear";
9const MAINNET_INVERSE: &str = "wss://stream.bybit.com/v5/public/inverse";
10const TESTNET_LINEAR: &str = "wss://stream-testnet.bybit.com/v5/public/linear";
11const TESTNET_INVERSE: &str = "wss://stream-testnet.bybit.com/v5/public/inverse";
12
13pub enum OrderbookDepth {
14    Level1,
15    Level50,
16    Level200,
17    Level500,
18}
19
20impl From<OrderbookDepth> for u16 {
21    fn from(value: OrderbookDepth) -> Self {
22        use OrderbookDepth::*;
23        match value {
24            Level1 => 1,
25            Level50 => 50,
26            Level200 => 200,
27            Level500 => 500,
28        }
29    }
30}
31
32pub struct FutureWebsocketApiClient {
33    uri: String,
34    subscriber: Subscriber,
35}
36
37impl FutureWebsocketApiClient {
38    pub fn subscribe_orderbook<S: AsRef<str>>(&mut self, symbol: S, depth: OrderbookDepth) {
39        self.subscriber.sub_orderbook(symbol.as_ref(), depth.into());
40    }
41
42    pub fn subscribe_trade<S: AsRef<str>>(&mut self, symbol: S) {
43        self.subscriber.sub_trade(symbol.as_ref());
44    }
45
46    pub fn subscribe_ticker<S: AsRef<str>>(&mut self, symbol: S) {
47        self.subscriber.sub_ticker(symbol.as_ref());
48    }
49
50    pub fn subscribe_kline<S: AsRef<str>>(&mut self, symbol: S, interval: KlineInterval) {
51        self.subscriber.sub_kline(symbol.as_ref(), interval.into());
52    }
53
54    pub fn subscribe_liquidation<S: AsRef<str>>(&mut self, symbol: S) {
55        self.subscriber.sub_liquidation(symbol.as_ref());
56    }
57
58    pub fn run<C: Callback<FuturePublicResponseArg>>(&self, callback: C) -> Result<()> {
59        run(&self.uri, self.subscriber.topics(), None, callback)
60    }
61}
62
63pub struct FutureWebSocketApiClientBuilder {
64    uri: String,
65    role: FutureRole,
66}
67
68impl FutureWebSocketApiClientBuilder {
69    /// Create a new `FutureWebSocketApiClientBuilder`. Channel URI is set to the mainnet.
70    pub fn new(role: FutureRole) -> Self {
71        let uri = match role {
72            FutureRole::Linear => MAINNET_LINEAR.to_string(),
73            FutureRole::Inverse => MAINNET_INVERSE.to_string(),
74        };
75        Self { uri, role }
76    }
77
78    /// Change channel URI to the testnet.
79    pub fn testnet(mut self) -> Self {
80        self.uri = match self.role {
81            FutureRole::Linear => TESTNET_LINEAR.to_string(),
82            FutureRole::Inverse => TESTNET_INVERSE.to_string(),
83        };
84        self
85    }
86
87    /// Set channel URI to the URI specified.
88    ///
89    /// Note URI should **match** with api client kind.
90    /// Do not set a spot channel URI to a future api client.
91    pub fn uri<S: AsRef<str>>(mut self, uri: S) -> Self {
92        self.uri = uri.as_ref().to_owned();
93        self
94    }
95
96    /// Build a future websocket api client.
97    pub fn build(self) -> FutureWebsocketApiClient {
98        FutureWebsocketApiClient {
99            uri: self.uri,
100            subscriber: Subscriber::new(),
101        }
102    }
103}