webull_rs/streaming/
subscription.rs

1use serde::{Deserialize, Serialize};
2
3/// Subscription type for WebSocket messages.
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
5#[serde(rename_all = "UPPERCASE")]
6pub enum SubscriptionType {
7    /// Quote subscription
8    Quote,
9
10    /// Order subscription
11    Order,
12
13    /// Account subscription
14    Account,
15
16    /// Trade subscription
17    Trade,
18}
19
20/// Subscription request for WebSocket messages.
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct SubscriptionRequest {
23    /// Subscription type
24    #[serde(rename = "type")]
25    pub subscription_type: SubscriptionType,
26
27    /// Symbols to subscribe to (for quote subscriptions)
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub symbols: Option<Vec<String>>,
30
31    /// Account ID to subscribe to (for order, account, and trade subscriptions)
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub account_id: Option<String>,
34}
35
36impl SubscriptionRequest {
37    /// Create a new quote subscription request.
38    pub fn new_quote(symbols: Vec<String>) -> Self {
39        Self {
40            subscription_type: SubscriptionType::Quote,
41            symbols: Some(symbols),
42            account_id: None,
43        }
44    }
45
46    /// Create a new order subscription request.
47    pub fn new_order(account_id: String) -> Self {
48        Self {
49            subscription_type: SubscriptionType::Order,
50            symbols: None,
51            account_id: Some(account_id),
52        }
53    }
54
55    /// Create a new account subscription request.
56    pub fn new_account(account_id: String) -> Self {
57        Self {
58            subscription_type: SubscriptionType::Account,
59            symbols: None,
60            account_id: Some(account_id),
61        }
62    }
63
64    /// Create a new trade subscription request.
65    pub fn new_trade(account_id: String) -> Self {
66        Self {
67            subscription_type: SubscriptionType::Trade,
68            symbols: None,
69            account_id: Some(account_id),
70        }
71    }
72}
73
74/// Unsubscription request for WebSocket messages.
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct UnsubscriptionRequest {
77    /// Subscription type
78    #[serde(rename = "type")]
79    pub subscription_type: SubscriptionType,
80
81    /// Symbols to unsubscribe from (for quote subscriptions)
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub symbols: Option<Vec<String>>,
84
85    /// Account ID to unsubscribe from (for order, account, and trade subscriptions)
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub account_id: Option<String>,
88}
89
90impl UnsubscriptionRequest {
91    /// Create a new quote unsubscription request.
92    pub fn new_quote(symbols: Vec<String>) -> Self {
93        Self {
94            subscription_type: SubscriptionType::Quote,
95            symbols: Some(symbols),
96            account_id: None,
97        }
98    }
99
100    /// Create a new order unsubscription request.
101    pub fn new_order(account_id: String) -> Self {
102        Self {
103            subscription_type: SubscriptionType::Order,
104            symbols: None,
105            account_id: Some(account_id),
106        }
107    }
108
109    /// Create a new account unsubscription request.
110    pub fn new_account(account_id: String) -> Self {
111        Self {
112            subscription_type: SubscriptionType::Account,
113            symbols: None,
114            account_id: Some(account_id),
115        }
116    }
117
118    /// Create a new trade unsubscription request.
119    pub fn new_trade(account_id: String) -> Self {
120        Self {
121            subscription_type: SubscriptionType::Trade,
122            symbols: None,
123            account_id: Some(account_id),
124        }
125    }
126}