1use crate::model::order::OrderInfo;
8use crate::model::order_management::QuoteResult;
9use crate::model::trade::{LastTrade, TradeExecution};
10use crate::{impl_json_debug_pretty, impl_json_display};
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct JsonRpcResponse<T> {
16 pub jsonrpc: String,
18 pub id: Option<serde_json::Value>,
20 pub result: Option<T>,
22 pub error: Option<JsonRpcError>,
24 pub testnet: Option<bool>,
26 #[serde(rename = "usIn")]
28 pub us_in: Option<i64>,
29 #[serde(rename = "usOut")]
31 pub us_out: Option<i64>,
32 #[serde(rename = "usDiff")]
34 pub us_diff: Option<i64>,
35}
36
37impl<T> JsonRpcResponse<T> {
38 pub fn success(id: Option<serde_json::Value>, result: T) -> Self {
40 Self {
41 jsonrpc: "2.0".to_string(),
42 id,
43 result: Some(result),
44 error: None,
45 testnet: None,
46 us_in: None,
47 us_out: None,
48 us_diff: None,
49 }
50 }
51
52 pub fn error(id: Option<serde_json::Value>, error: JsonRpcError) -> Self {
54 Self {
55 jsonrpc: "2.0".to_string(),
56 id,
57 result: None,
58 error: Some(error),
59 testnet: None,
60 us_in: None,
61 us_out: None,
62 us_diff: None,
63 }
64 }
65
66 pub fn is_success(&self) -> bool {
68 self.error.is_none() && self.result.is_some()
69 }
70
71 pub fn is_error(&self) -> bool {
73 self.error.is_some()
74 }
75
76 pub fn into_result(self) -> Result<T, JsonRpcError> {
78 match (self.result, self.error) {
79 (Some(result), None) => Ok(result),
80 (None, Some(error)) => Err(error),
81 (Some(_), Some(error)) => Err(error), (None, None) => Err(JsonRpcError {
83 code: -32603,
84 message: "Internal error: neither result nor error present".to_string(),
85 data: None,
86 }),
87 }
88 }
89}
90
91#[derive(Clone, Serialize, Deserialize)]
93pub struct JsonRpcError {
94 pub code: i32,
96 pub message: String,
98 pub data: Option<serde_json::Value>,
100}
101
102impl JsonRpcError {
103 pub fn new(code: i32, message: String) -> Self {
105 Self {
106 code,
107 message,
108 data: None,
109 }
110 }
111
112 pub fn with_data(code: i32, message: String, data: serde_json::Value) -> Self {
114 Self {
115 code,
116 message,
117 data: Some(data),
118 }
119 }
120
121 pub fn parse_error() -> Self {
123 Self::new(-32700, "Parse error".to_string())
124 }
125
126 pub fn invalid_request() -> Self {
128 Self::new(-32600, "Invalid Request".to_string())
129 }
130
131 pub fn method_not_found() -> Self {
133 Self::new(-32601, "Method not found".to_string())
134 }
135
136 pub fn invalid_params() -> Self {
138 Self::new(-32602, "Invalid params".to_string())
139 }
140
141 pub fn internal_error() -> Self {
143 Self::new(-32603, "Internal error".to_string())
144 }
145
146 pub fn is_server_error(&self) -> bool {
148 self.code <= -32000 && self.code >= -32099
149 }
150
151 pub fn is_application_error(&self) -> bool {
153 self.code > -32000
154 }
155}
156
157#[derive(Clone, Serialize, Deserialize)]
159pub struct AuthResponse {
160 pub access_token: String,
162 pub token_type: String,
164 pub expires_in: i64,
166 pub refresh_token: String,
168 pub scope: String,
170}
171
172#[derive(Clone, Serialize, Deserialize)]
174pub struct Pagination {
175 pub page: Option<u32>,
177 pub per_page: Option<u32>,
179 pub total: Option<u64>,
181 pub pages: Option<u32>,
183 pub has_more: Option<bool>,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct PaginatedResponse<T> {
190 pub data: Vec<T>,
192 pub pagination: Option<Pagination>,
194}
195
196impl<T> PaginatedResponse<T> {
197 pub fn new(data: Vec<T>) -> Self {
199 Self {
200 data,
201 pagination: None,
202 }
203 }
204
205 pub fn with_pagination(data: Vec<T>, pagination: Pagination) -> Self {
207 Self {
208 data,
209 pagination: Some(pagination),
210 }
211 }
212
213 pub fn has_more(&self) -> bool {
215 self.pagination
216 .as_ref()
217 .and_then(|p| p.has_more)
218 .unwrap_or(false)
219 }
220
221 pub fn len(&self) -> usize {
223 self.data.len()
224 }
225
226 pub fn is_empty(&self) -> bool {
228 self.data.is_empty()
229 }
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct Notification<T> {
235 pub jsonrpc: String,
237 pub method: String,
239 pub params: T,
241}
242
243impl<T> Notification<T> {
244 pub fn new(method: String, params: T) -> Self {
246 Self {
247 jsonrpc: "2.0".to_string(),
248 method,
249 params,
250 }
251 }
252}
253
254#[derive(Clone, Serialize, Deserialize)]
256pub struct SubscriptionResponse {
257 pub subscription: String,
259 pub channel: String,
261}
262
263#[derive(Clone, Serialize, Deserialize)]
265pub struct HeartbeatResponse {
266 #[serde(rename = "type")]
268 pub type_: String,
269}
270
271#[derive(Clone, Serialize, Deserialize)]
273pub struct TestResponse {
274 pub version: String,
276}
277
278#[derive(Clone, Serialize, Deserialize)]
280pub struct ServerTimeResponse {
281 pub timestamp: i64,
283}
284
285#[derive(Clone, Serialize, Deserialize)]
287pub struct SettlementsResponse {
288 pub continuation: Option<String>,
290 pub settlements: Vec<crate::model::settlement::Settlement>,
292}
293
294impl SettlementsResponse {
295 pub fn new(settlements: Vec<crate::model::settlement::Settlement>) -> Self {
297 Self {
298 continuation: None,
299 settlements,
300 }
301 }
302
303 pub fn with_continuation(
305 settlements: Vec<crate::model::settlement::Settlement>,
306 continuation: String,
307 ) -> Self {
308 Self {
309 continuation: Some(continuation),
310 settlements,
311 }
312 }
313
314 pub fn has_more(&self) -> bool {
316 self.continuation.is_some()
317 }
318}
319
320#[derive(Clone, Serialize, Deserialize)]
322pub struct ContractSizeResponse {
323 pub contract_size: f64,
325}
326
327#[derive(Clone, Serialize, Deserialize)]
329pub struct StatusResponse {
330 pub locked: Option<bool>,
332 pub message: Option<String>,
334 pub locked_indices: Option<Vec<String>>,
336 #[serde(flatten)]
338 pub additional_fields: std::collections::HashMap<String, serde_json::Value>,
339}
340
341#[derive(Clone, Serialize, Deserialize)]
343pub struct AprHistoryResponse {
344 pub data: Vec<AprDataPoint>,
346 pub continuation: Option<String>,
348}
349#[derive(Clone, Serialize, Deserialize)]
351pub struct AprDataPoint {
352 pub apr: f64,
354 pub timestamp: Option<u64>,
356 pub day: i32,
358}
359
360#[derive(Clone, Serialize, Deserialize)]
362pub struct HelloResponse {
363 pub version: String,
365}
366
367#[derive(Clone, Serialize, Deserialize)]
369pub struct DeliveryPricesResponse {
370 pub data: Vec<DeliveryPriceData>,
372 pub records_total: u32,
374}
375
376#[derive(Clone, Serialize, Deserialize)]
378pub struct DeliveryPriceData {
379 pub date: String,
381 pub delivery_price: f64,
383}
384
385#[derive(Clone, Serialize, Deserialize)]
387pub struct CurrencyExpirations {
388 pub future: Option<Vec<String>>,
390 pub option: Option<Vec<String>>,
392}
393
394#[derive(Clone, Serialize, Deserialize)]
396pub struct ExpirationsResponse {
397 pub future: Option<Vec<String>>,
399 pub option: Option<Vec<String>>,
401 #[serde(flatten)]
403 pub currencies: std::collections::HashMap<String, CurrencyExpirations>,
404}
405
406#[derive(Clone, Serialize, Deserialize)]
408pub struct LastTradesResponse {
409 pub has_more: bool,
411 pub trades: Vec<LastTrade>,
413}
414
415#[derive(Clone, Serialize, Deserialize)]
417pub struct OrderResponse {
418 pub order: OrderInfo,
420 pub trades: Vec<TradeExecution>,
422}
423
424#[derive(Clone, Serialize, Deserialize)]
426pub struct MassQuoteResponse {
427 pub quotes: Vec<QuoteResult>,
429}
430
431impl_json_display!(
432 MassQuoteResponse,
433 JsonRpcError,
434 AuthResponse,
435 Pagination,
436 SubscriptionResponse,
437 HeartbeatResponse,
438 TestResponse,
439 ServerTimeResponse,
440 SettlementsResponse,
441 ContractSizeResponse,
442 StatusResponse,
443 AprHistoryResponse,
444 AprDataPoint,
445 HelloResponse,
446 DeliveryPricesResponse,
447 DeliveryPriceData,
448 CurrencyExpirations,
449 ExpirationsResponse,
450 LastTradesResponse,
451 OrderResponse
452);
453impl_json_debug_pretty!(
454 MassQuoteResponse,
455 JsonRpcError,
456 AuthResponse,
457 Pagination,
458 SubscriptionResponse,
459 HeartbeatResponse,
460 TestResponse,
461 ServerTimeResponse,
462 SettlementsResponse,
463 ContractSizeResponse,
464 StatusResponse,
465 AprHistoryResponse,
466 AprDataPoint,
467 HelloResponse,
468 DeliveryPricesResponse,
469 DeliveryPriceData,
470 CurrencyExpirations,
471 ExpirationsResponse,
472 LastTradesResponse,
473 OrderResponse
474);
475
476impl std::error::Error for JsonRpcError {}