projectx_client/realtime/
session_handle.rs1use super::{
5 AccountId, ContractId, Hub, RealtimeError, RealtimeGeneration, RealtimeInner, Value, Weak,
6};
7
8#[derive(Clone)]
11pub struct RealtimeSession {
12 pub(super) inner: Weak<RealtimeInner>,
13 pub(super) generation: RealtimeGeneration,
14}
15
16impl RealtimeSession {
17 #[must_use]
19 pub const fn generation(&self) -> RealtimeGeneration {
20 self.generation
21 }
22
23 pub async fn invoke(
32 &self,
33 target: impl Into<String>,
34 arguments: Vec<Value>,
35 ) -> Result<(), RealtimeError> {
36 self.send_invocation(target.into(), arguments).await
37 }
38
39 pub async fn subscribe_contract_trades(
45 &self,
46 contract: &ContractId,
47 ) -> Result<(), RealtimeError> {
48 self.ensure_hub(Hub::Market)?;
49 self.contract_invocation("SubscribeContractTrades", contract)
50 .await
51 }
52
53 pub async fn unsubscribe_contract_trades(
59 &self,
60 contract: &ContractId,
61 ) -> Result<(), RealtimeError> {
62 self.ensure_hub(Hub::Market)?;
63 self.contract_invocation("UnsubscribeContractTrades", contract)
64 .await
65 }
66
67 pub async fn subscribe_contract_quotes(
73 &self,
74 contract: &ContractId,
75 ) -> Result<(), RealtimeError> {
76 self.ensure_hub(Hub::Market)?;
77 self.contract_invocation("SubscribeContractQuotes", contract)
78 .await
79 }
80
81 pub async fn unsubscribe_contract_quotes(
87 &self,
88 contract: &ContractId,
89 ) -> Result<(), RealtimeError> {
90 self.ensure_hub(Hub::Market)?;
91 self.contract_invocation("UnsubscribeContractQuotes", contract)
92 .await
93 }
94
95 pub async fn subscribe_contract_depth(
101 &self,
102 contract: &ContractId,
103 ) -> Result<(), RealtimeError> {
104 self.ensure_hub(Hub::Market)?;
105 self.contract_invocation("SubscribeContractMarketDepth", contract)
106 .await
107 }
108
109 pub async fn unsubscribe_contract_depth(
115 &self,
116 contract: &ContractId,
117 ) -> Result<(), RealtimeError> {
118 self.ensure_hub(Hub::Market)?;
119 self.contract_invocation("UnsubscribeContractMarketDepth", contract)
120 .await
121 }
122
123 pub async fn subscribe_accounts(&self) -> Result<(), RealtimeError> {
129 self.ensure_hub(Hub::User)?;
130 self.send_invocation("SubscribeAccounts".to_owned(), Vec::new())
131 .await
132 }
133
134 pub async fn unsubscribe_accounts(&self) -> Result<(), RealtimeError> {
140 self.ensure_hub(Hub::User)?;
141 self.send_invocation("UnsubscribeAccounts".to_owned(), Vec::new())
142 .await
143 }
144
145 pub async fn subscribe_orders(&self, account: AccountId) -> Result<(), RealtimeError> {
151 self.ensure_hub(Hub::User)?;
152 self.account_invocation("SubscribeOrders", account).await
153 }
154
155 pub async fn unsubscribe_orders(&self, account: AccountId) -> Result<(), RealtimeError> {
161 self.ensure_hub(Hub::User)?;
162 self.account_invocation("UnsubscribeOrders", account).await
163 }
164
165 pub async fn subscribe_positions(&self, account: AccountId) -> Result<(), RealtimeError> {
171 self.ensure_hub(Hub::User)?;
172 self.account_invocation("SubscribePositions", account).await
173 }
174
175 pub async fn unsubscribe_positions(&self, account: AccountId) -> Result<(), RealtimeError> {
181 self.ensure_hub(Hub::User)?;
182 self.account_invocation("UnsubscribePositions", account)
183 .await
184 }
185
186 pub async fn subscribe_trades(&self, account: AccountId) -> Result<(), RealtimeError> {
192 self.ensure_hub(Hub::User)?;
193 self.account_invocation("SubscribeTrades", account).await
194 }
195
196 pub async fn unsubscribe_trades(&self, account: AccountId) -> Result<(), RealtimeError> {
202 self.ensure_hub(Hub::User)?;
203 self.account_invocation("UnsubscribeTrades", account).await
204 }
205
206 fn ensure_hub(&self, expected: Hub) -> Result<(), RealtimeError> {
207 if self.inner.upgrade().ok_or(RealtimeError::NotConnected)?.hub == expected {
208 Ok(())
209 } else {
210 Err(RealtimeError::WrongHub)
211 }
212 }
213
214 async fn contract_invocation(
215 &self,
216 target: &str,
217 contract: &ContractId,
218 ) -> Result<(), RealtimeError> {
219 self.inner
220 .upgrade()
221 .ok_or(RealtimeError::NotConnected)?
222 .send_invocation(
223 Some(self.generation),
224 target.to_owned(),
225 vec![Value::String(contract.to_string())],
226 )
227 .await
228 }
229
230 async fn account_invocation(
231 &self,
232 target: &str,
233 account: AccountId,
234 ) -> Result<(), RealtimeError> {
235 self.inner
236 .upgrade()
237 .ok_or(RealtimeError::NotConnected)?
238 .send_invocation(
239 Some(self.generation),
240 target.to_owned(),
241 vec![Value::from(account.get())],
242 )
243 .await
244 }
245
246 async fn send_invocation(
247 &self,
248 target: String,
249 arguments: Vec<Value>,
250 ) -> Result<(), RealtimeError> {
251 self.inner
252 .upgrade()
253 .ok_or(RealtimeError::NotConnected)?
254 .send_invocation(Some(self.generation), target, arguments)
255 .await
256 }
257}
258
259impl std::fmt::Debug for RealtimeSession {
260 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
261 f.debug_struct("RealtimeSession")
262 .field("generation", &self.generation)
263 .finish_non_exhaustive()
264 }
265}