Skip to main content

bybit/http/
common.rs

1use serde::Deserialize;
2
3use crate::{Timestamp, enums::Category, serde::empty_string_as_none};
4
5/// Raw response envelope of the Bybit REST API.
6#[derive(Debug, Deserialize, PartialEq)]
7#[serde(rename_all = "camelCase")]
8pub struct Resp<T> {
9    /// Bybit `retCode`, 0 on success.
10    pub ret_code: i64,
11    /// Bybit `retMsg`.
12    pub ret_msg: String,
13    /// Endpoint-specific result.
14    pub result: T,
15    /// Server time of the response, milliseconds.
16    pub time: Option<Timestamp>,
17    /// Per-item results of batch endpoints.
18    pub ret_ext_info: Option<RetExtInfo>,
19}
20
21/// Error part of the response envelope.
22#[derive(Debug, Deserialize, PartialEq)]
23#[serde(rename_all = "camelCase")]
24pub struct APIErrorResponse {
25    /// Bybit `retCode`.
26    pub ret_code: i64,
27    /// Bybit `retMsg`.
28    pub ret_msg: String,
29}
30
31/// A successful REST response.
32#[derive(Debug, PartialEq)]
33pub struct Response<T> {
34    /// Endpoint-specific result.
35    pub result: T,
36    /// Server time of the response, milliseconds.
37    pub time: Option<Timestamp>,
38    /// Selected response headers (rate limit status, trace id).
39    pub headers: Headers,
40    /// Per-item results for batch endpoints; `None` for all non-batch calls.
41    pub ret_ext_info: Option<RetExtInfo>,
42}
43
44/// A page of a cursor-paginated list.
45#[derive(Debug, Deserialize, PartialEq)]
46#[serde(rename_all = "camelCase")]
47pub struct CursorPagination<T> {
48    /// Product type, if the endpoint returns it.
49    pub category: Option<Category>,
50    /// Cursor of the next page; `None` on the last page.
51    #[serde(default, deserialize_with = "empty_string_as_none")]
52    pub next_page_cursor: Option<String>,
53    /// Items of this page.
54    pub list: Vec<T>,
55}
56
57/// A list result without pagination.
58#[derive(Debug, Deserialize, PartialEq)]
59#[serde(rename_all = "camelCase")]
60pub struct List<T> {
61    /// Items.
62    pub list: Vec<T>,
63}
64
65/// Response headers parsed by the client.
66#[derive(Debug, PartialEq)]
67pub struct Headers {
68    /// `ret_code` header.
69    pub ret_code: Option<i32>,
70    /// `traceid` header, useful when contacting Bybit support.
71    pub trace_id: Option<String>,
72    /// `timenow` header: server time, milliseconds.
73    pub time_now: Option<Timestamp>,
74    /// `X-Bapi-Limit`: the limit of this endpoint.
75    pub api_limit: Option<u64>,
76    /// `X-Bapi-Limit-Status`: remaining requests in the current window.
77    pub api_limit_status: Option<u64>,
78    /// `X-Bapi-Limit-Reset-Timestamp`: when the window resets, milliseconds.
79    pub api_limit_reset_timestamp: Option<Timestamp>,
80}
81
82impl Headers {
83    /// `true` if the `ret_code` header is 0.
84    pub fn is_ret_code_ok(&self) -> bool {
85        match self.ret_code {
86            Some(code) => code == 0,
87            None => false,
88        }
89    }
90}
91
92/// Result of one item of a batch request.
93#[derive(Debug, Clone, Deserialize, PartialEq)]
94pub struct BatchItemResult {
95    /// Item `retCode`, 0 on success.
96    pub code: i64,
97    /// Item `retMsg`.
98    pub msg: String,
99}
100
101/// Per-item status for batch trade endpoints.
102/// For all other endpoints `retExtInfo` is `{}` — the `list` defaults to empty.
103#[derive(Debug, Clone, Default, Deserialize, PartialEq)]
104pub struct RetExtInfo {
105    /// One result per item of the batch, in request order.
106    #[serde(default)]
107    pub list: Vec<BatchItemResult>,
108}
109
110/// Returned by position-management and other void-result endpoints whose
111/// `result` field is the empty object `{}`.
112#[derive(Debug, Deserialize, PartialEq)]
113pub struct EmptyResult {}