binance_sdk/common/
models.rs

1use derive_builder::UninitializedFieldError;
2use serde::de::DeserializeOwned;
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::fmt;
6use std::marker::PhantomData;
7use std::{collections::HashMap, future::Future, pin::Pin};
8use thiserror::Error;
9
10use super::errors::ConnectorError;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum TimeUnit {
14    Millisecond,
15    Microsecond,
16}
17
18impl fmt::Display for TimeUnit {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        match self {
21            TimeUnit::Millisecond => write!(f, "millisecond"),
22            TimeUnit::Microsecond => write!(f, "microsecond"),
23        }
24    }
25}
26
27impl TimeUnit {
28    #[must_use]
29    pub fn as_upper_str(&self) -> &'static str {
30        match self {
31            TimeUnit::Millisecond => "MILLISECOND",
32            TimeUnit::Microsecond => "MICROSECOND",
33        }
34    }
35    #[must_use]
36    pub fn as_lower_str(&self) -> &'static str {
37        match self {
38            TimeUnit::Millisecond => "millisecond",
39            TimeUnit::Microsecond => "microsecond",
40        }
41    }
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
45#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
46pub enum RateLimitType {
47    RequestWeight,
48    Orders,
49    RawRequests,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
54pub enum Interval {
55    Second,
56    Minute,
57    Hour,
58    Day,
59}
60
61#[derive(Debug, Clone)]
62pub struct RestApiRateLimit {
63    pub rate_limit_type: RateLimitType,
64    pub interval: Interval,
65    pub interval_num: u32,
66    pub count: u32,
67    pub retry_after: Option<u32>,
68}
69
70pub type DataFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
71
72pub struct RestApiResponse<T> {
73    pub(crate) data_fn: Box<
74        dyn FnOnce() -> Pin<Box<dyn Future<Output = Result<T, ConnectorError>> + Send>>
75            + Send
76            + Sync,
77    >,
78    pub status: u16,
79    pub headers: HashMap<String, String>,
80    pub rate_limits: Option<Vec<RestApiRateLimit>>,
81}
82
83impl<T> RestApiResponse<T>
84where
85    T: Send + 'static,
86{
87    /// Executes the data retrieval function and returns the result.
88    ///
89    /// # Returns
90    ///
91    /// A `Result` containing the data of type `T` if successful,
92    /// or a `ConnectorError` if the operation fails.
93    ///
94    /// # Errors
95    ///
96    /// Returns an error if the operation fails.
97    ///
98    /// # Examples
99    ///
100    ///
101    /// let response: `RestApiResponse`<MyType> = ...;
102    /// let data = response.data().await?;
103    ///
104    pub async fn data(self) -> Result<T, ConnectorError> {
105        (self.data_fn)().await
106    }
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
110pub struct WebsocketApiRateLimit {
111    #[serde(rename = "rateLimitType")]
112    pub rate_limit_type: RateLimitType,
113    #[serde(rename = "interval")]
114    pub interval: Interval,
115    #[serde(rename = "intervalNum")]
116    pub interval_num: u32,
117    pub limit: u32,
118    pub count: Option<u32>,
119}
120
121#[derive(Debug)]
122pub struct WebsocketApiResponse<T> {
123    pub(crate) _marker: PhantomData<T>,
124
125    pub raw: Value,
126    pub rate_limits: Option<Vec<WebsocketApiRateLimit>>,
127}
128
129impl<T> WebsocketApiResponse<T>
130where
131    T: DeserializeOwned,
132{
133    /// Deserializes the raw JSON value into the generic type `T`.
134    ///
135    /// # Returns
136    ///
137    /// A `Result` containing the deserialized value of type `T` if successful,
138    /// or a `serde_json::Error` if deserialization fails.
139    ///
140    /// # Errors
141    ///
142    /// Returns an error if deserialization fails.
143    ///
144    /// # Examples
145    ///
146    ///
147    /// // Assuming `WebsocketApiResponse` contains a raw JSON value
148    /// let response: `WebsocketApiResponse`<MyType> = ...;
149    /// let data = `response.data()`?;
150    ///
151    pub fn data(self) -> serde_json::Result<T> {
152        serde_json::from_value(self.raw)
153    }
154}
155
156#[derive(Debug, Error)]
157pub enum ParamBuildError {
158    #[error("missing required field `{0}`")]
159    UninitializedField(&'static str),
160}
161
162impl From<UninitializedFieldError> for ParamBuildError {
163    fn from(err: UninitializedFieldError) -> Self {
164        ParamBuildError::UninitializedField(err.field_name())
165    }
166}
167
168#[derive(Debug, Error)]
169pub enum ConfigBuildError {
170    #[error("Configuration missing or invalid `{0}`")]
171    UninitializedField(&'static str),
172}
173
174impl From<UninitializedFieldError> for ConfigBuildError {
175    fn from(err: UninitializedFieldError) -> Self {
176        ConfigBuildError::UninitializedField(err.field_name())
177    }
178}
179
180#[derive(Debug, Clone, PartialEq)]
181pub enum WebsocketEvent {
182    Open,
183    Message(String),
184    Error(String),
185    Close(u16, String),
186    Ping,
187    Pong,
188}
189
190#[derive(Debug, Clone, PartialEq)]
191pub enum WebsocketMode {
192    Single,
193    Pool(usize),
194}
195
196impl WebsocketMode {
197    #[must_use]
198    pub fn pool_size(&self) -> usize {
199        match *self {
200            WebsocketMode::Single => 1,
201            WebsocketMode::Pool(sz) => sz,
202        }
203    }
204}
205
206#[derive(Debug, Clone, Default)]
207pub struct WebsocketApiConnectConfig {
208    pub mode: Option<WebsocketMode>,
209}
210
211#[derive(Debug, Clone, Default)]
212pub struct WebsocketStreamsConnectConfig {
213    pub streams: Vec<String>,
214    pub mode: Option<WebsocketMode>,
215}