Skip to main content

bybit_client/types/
common.rs

1//! Common types shared across the API.
2
3use serde::{Deserialize, Serialize};
4
5/// Server time response.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct ServerTime {
9    /// Server time in seconds (string).
10    pub time_second: String,
11    /// Server time in nanoseconds (string).
12    pub time_nano: String,
13}
14
15impl ServerTime {
16    /// Get the server time in milliseconds.
17    pub fn as_millis(&self) -> u64 {
18        self.time_nano
19            .parse::<u64>()
20            .map(|ns| ns / 1_000_000)
21            .unwrap_or(0)
22    }
23}
24
25/// Rate limit information parsed from response headers.
26#[derive(Debug, Clone, Default)]
27pub struct RateLimitInfo {
28    /// Remaining requests in the current window.
29    pub remaining: Option<u32>,
30    /// Maximum requests per window.
31    pub limit: Option<u32>,
32    /// Reset timestamp in milliseconds.
33    pub reset_at: Option<u64>,
34}
35
36/// Generic cursor-based pagination parameters.
37#[derive(Debug, Clone, Default, Serialize)]
38#[serde(rename_all = "camelCase")]
39pub struct PaginationParams {
40    /// Maximum number of items to return.
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub limit: Option<u32>,
43    /// Cursor for pagination.
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub cursor: Option<String>,
46}
47
48impl PaginationParams {
49    /// Create new pagination parameters.
50    pub fn new() -> Self {
51        Self::default()
52    }
53
54    /// Set the limit.
55    pub fn limit(mut self, limit: u32) -> Self {
56        self.limit = Some(limit);
57        self
58    }
59
60    /// Set the cursor.
61    pub fn cursor(mut self, cursor: impl Into<String>) -> Self {
62        self.cursor = Some(cursor.into());
63        self
64    }
65}
66
67/// Empty result type for endpoints that return no data.
68#[derive(Debug, Clone, Default, Serialize, Deserialize)]
69pub struct Empty {}
70
71/// Symbol information base fields (common across categories).
72#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(rename_all = "camelCase")]
74pub struct SymbolInfo {
75    /// Trading symbol.
76    pub symbol: String,
77    /// Base currency.
78    #[serde(default)]
79    pub base_coin: Option<String>,
80    /// Quote currency.
81    #[serde(default)]
82    pub quote_coin: Option<String>,
83    /// Symbol status.
84    #[serde(default)]
85    pub status: Option<String>,
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn test_server_time() {
94        let st = ServerTime {
95            time_second: "1699123456".to_string(),
96            time_nano: "1699123456789000000".to_string(),
97        };
98        assert_eq!(st.as_millis(), 1699123456789);
99    }
100
101    #[test]
102    fn test_pagination() {
103        let params = PaginationParams::new().limit(50).cursor("abc123");
104        assert_eq!(params.limit, Some(50));
105        assert_eq!(params.cursor, Some("abc123".to_string()));
106    }
107}